datex_core/ast/
mod.rs

1pub mod assignment_operation;
2pub mod atom;
3pub mod binary_operation;
4pub mod binding;
5pub mod chain;
6pub mod comparison_operation;
7pub mod decimal;
8pub mod endpoint;
9pub mod error;
10pub mod function;
11pub mod integer;
12pub mod key;
13pub mod lexer;
14pub mod list;
15pub mod literal;
16pub mod map;
17pub mod text;
18pub mod r#type;
19pub mod unary;
20pub mod unary_operation;
21pub mod utils;
22
23use crate::ast::assignment_operation::*;
24use crate::ast::atom::*;
25use crate::ast::binary_operation::*;
26use crate::ast::binding::*;
27use crate::ast::chain::*;
28use crate::ast::comparison_operation::*;
29use crate::ast::error::error::ParseError;
30use crate::ast::error::pattern::Pattern;
31use crate::ast::function::*;
32use crate::ast::key::*;
33use crate::ast::list::*;
34use crate::ast::map::*;
35use crate::ast::r#type::type_expression;
36use crate::ast::unary::*;
37use crate::ast::unary_operation::*;
38use crate::ast::utils::*;
39
40use crate::values::core_value::CoreValue;
41use crate::values::core_values::decimal::Decimal;
42use crate::values::core_values::decimal::typed_decimal::TypedDecimal;
43use crate::values::core_values::endpoint::Endpoint;
44use crate::values::core_values::integer::Integer;
45use crate::values::core_values::integer::typed_integer::TypedInteger;
46use crate::values::core_values::list::List;
47use crate::values::core_values::map::Map;
48use crate::values::core_values::r#type::Type;
49use crate::values::pointer::PointerAddress;
50use crate::values::value::Value;
51use crate::values::value_container::ValueContainer;
52use chumsky::extra::Err;
53use chumsky::prelude::*;
54use lexer::Token;
55use logos::Logos;
56use std::ops::Neg;
57use std::ops::Range;
58
59pub type TokenInput<'a, X = Token> = &'a [X];
60pub trait DatexParserTrait<'a, T = DatexExpression, X = Token> =
61    Parser<'a, TokenInput<'a, Token>, T, Err<ParseError>> + Clone + 'a
62    where X: PartialEq + 'a;
63
64pub type DatexScriptParser<'a> =
65    Boxed<'a, 'a, TokenInput<'a>, DatexExpression, Err<ParseError>>;
66
67#[derive(Clone, Debug, PartialEq)]
68pub struct Statement {
69    pub expression: DatexExpression,
70    pub is_terminated: bool,
71}
72pub trait ParserRecoverExt<'a, I>:
73    DatexParserTrait<'a, Result<DatexExpression, I>>
74where
75    I: 'a + Into<ParseError>,
76{
77    fn recover_invalid(self) -> impl DatexParserTrait<'a, DatexExpression>
78    where
79        Self: Sized,
80    {
81        self.validate(
82            |item: Result<DatexExpression, I>,
83             ctx,
84             emitter: &mut chumsky::input::Emitter<ParseError>| {
85                match item {
86                    Ok(expr) => expr,
87                    Err(err) => {
88                        let span = ctx.span();
89                        let mut error: ParseError = err.into();
90                        error.set_token_pos(span.start);
91                        emitter.emit(error);
92                        DatexExpression::Recover
93                    }
94                }
95            },
96        )
97    }
98}
99
100impl<'a, I, P> ParserRecoverExt<'a, I> for P
101where
102    I: 'a + Into<ParseError>,
103    P: DatexParserTrait<'a, Result<DatexExpression, I>>,
104{
105}
106
107#[derive(Clone, Copy, Debug, PartialEq)]
108pub enum VariableKind {
109    Const,
110    Var,
111}
112
113#[derive(Clone, Debug, PartialEq)]
114pub enum Slot {
115    Addressed(u32),
116    Named(String),
117}
118
119#[derive(Clone, Debug, PartialEq)]
120pub enum TypeExpression {
121    Null,
122    // a type name or variable, e.g. integer, string, User, MyType, T
123    Literal(String),
124
125    Variable(VariableId, String),
126    GetReference(PointerAddress),
127
128    // literals
129    Integer(Integer),
130    TypedInteger(TypedInteger),
131    Decimal(Decimal),
132    TypedDecimal(TypedDecimal),
133    Boolean(bool),
134    Text(String),
135    Endpoint(Endpoint),
136
137    // [integer, text, endpoint]
138    // size known to compile time, arbitrary types
139    StructuralList(Vec<TypeExpression>),
140
141    // [text; 3], integer[10]
142    // fixed size and known to compile time, only one type
143    FixedSizeList(Box<TypeExpression>, usize),
144
145    // text[], integer[]
146    // size not known to compile time, only one type
147    SliceList(Box<TypeExpression>),
148
149    // text & "test"
150    Intersection(Vec<TypeExpression>),
151
152    // text | integer
153    Union(Vec<TypeExpression>),
154
155    // User<text, integer>
156    Generic(String, Vec<TypeExpression>),
157
158    // (x: text) -> text
159    Function {
160        parameters: Vec<(String, TypeExpression)>,
161        return_type: Box<TypeExpression>,
162    },
163
164    // structurally typed map, e.g. { x: integer, y: text }
165    StructuralMap(Vec<(TypeExpression, TypeExpression)>),
166
167    // modifiers
168    Ref(Box<TypeExpression>),
169    RefMut(Box<TypeExpression>),
170    RefFinal(Box<TypeExpression>),
171}
172
173#[derive(Clone, Debug, PartialEq)]
174pub enum DatexExpression {
175    /// This is a marker for recovery from parse errors.
176    /// We should never use this manually.
177    Recover,
178
179    /// null
180    Null,
181    /// Boolean (true or false)
182    Boolean(bool),
183    /// Text, e.g "Hello, world!"
184    Text(String),
185    /// Decimal, e.g 123.456789123456
186    Decimal(Decimal),
187
188    /// Typed Decimal, e.g. 123.456i8
189    TypedDecimal(TypedDecimal),
190
191    /// Integer, e.g 123456789123456789
192    Integer(Integer),
193
194    /// Typed Integer, e.g. 123i8
195    TypedInteger(TypedInteger),
196
197    /// Identifier (variable / core type usage)
198    Identifier(String),
199
200    /// Endpoint, e.g. @test_a or @test_b
201    Endpoint(Endpoint),
202    /// List, e.g  `[1, 2, 3, "text"]`
203    List(Vec<DatexExpression>),
204    /// Map, e.g {"xy": 2, (3): 4, xy: "xy"}
205    Map(Vec<(DatexExpression, DatexExpression)>),
206    /// One or more statements, e.g (1; 2; 3)
207    Statements(Vec<Statement>),
208    /// Variable name - only generated by the precompiler, not by the parser
209    Variable(VariableId, String),
210    /// reference access, e.g. &<ABCDEF>
211    GetReference(PointerAddress),
212
213    /// Conditional expression, e.g. if (true) { 1 } else { 2 }
214    Conditional {
215        condition: Box<DatexExpression>,
216        then_branch: Box<DatexExpression>,
217        else_branch: Option<Box<DatexExpression>>,
218    },
219
220    // TODO #359: Give information on type kind (nominal & structural)
221    /// Variable declaration, e.g. const x = 1, const mut x = 1, or var y = 2. VariableId is always set to 0 by the ast parser.
222    VariableDeclaration {
223        id: Option<VariableId>,
224        kind: VariableKind,
225        name: String,
226        type_annotation: Option<TypeExpression>,
227        init_expression: Box<DatexExpression>,
228    },
229
230    // TODO #360: Shall we avoid hoisting for type aliases?
231    // This would remove the ability to have recursive type
232    // definitions.
233    /// Type declaration, e.g. type MyType = { x: 42, y: "John" };
234    TypeDeclaration {
235        id: Option<VariableId>,
236        name: String,
237        value: TypeExpression, // Type
238        hoisted: bool,
239    },
240
241    /// Type expression, e.g. { x: 42, y: "John" }
242    TypeExpression(TypeExpression),
243
244    /// Type keyword, e.g. type(...)
245    Type(TypeExpression),
246
247    FunctionDeclaration {
248        name: String,
249        parameters: Vec<(String, TypeExpression)>,
250        return_type: Option<TypeExpression>,
251        body: Box<DatexExpression>,
252    },
253
254    // TODO #361 combine
255    /// Reference, e.g. &x
256    CreateRef(Box<DatexExpression>),
257    /// Mutable reference, e.g. &mut x
258    CreateRefMut(Box<DatexExpression>),
259    /// Final reference, e.g. &final x
260    CreateRefFinal(Box<DatexExpression>),
261
262    /// Deref
263    Deref(Box<DatexExpression>),
264
265    /// Slot, e.g. #1, #endpoint
266    Slot(Slot),
267    /// Slot assignment
268    SlotAssignment(Slot, Box<DatexExpression>),
269
270    PointerAddress(PointerAddress),
271
272    // TODO #362 struct instead of tuple
273    BinaryOperation(
274        BinaryOperator,
275        Box<DatexExpression>,
276        Box<DatexExpression>,
277        Option<Type>,
278    ),
279    ComparisonOperation(
280        ComparisonOperator,
281        Box<DatexExpression>,
282        Box<DatexExpression>,
283    ),
284    VariableAssignment(
285        AssignmentOperator,
286        Option<VariableId>,
287        String,
288        Box<DatexExpression>,
289    ),
290    DerefAssignment {
291        operator: AssignmentOperator,
292        deref_count: usize,
293        deref_expression: Box<DatexExpression>,
294        assigned_expression: Box<DatexExpression>,
295    },
296    UnaryOperation(UnaryOperator, Box<DatexExpression>),
297
298    // apply (e.g. x (1)) or property access
299    ApplyChain(Box<DatexExpression>, Vec<ApplyOperation>),
300
301    // ?
302    Placeholder,
303    // @xy :: z
304    RemoteExecution(Box<DatexExpression>, Box<DatexExpression>),
305}
306
307// directly convert DatexExpression to a ValueContainer
308impl TryFrom<&DatexExpression> for ValueContainer {
309    type Error = ();
310
311    fn try_from(expr: &DatexExpression) -> Result<Self, Self::Error> {
312        Ok(match expr {
313            DatexExpression::UnaryOperation(op, expr) => {
314                let value = ValueContainer::try_from(expr.as_ref())?;
315                match value {
316                    ValueContainer::Value(Value {
317                        inner: CoreValue::Integer(_) | CoreValue::Decimal(_),
318                        ..
319                    }) => match op {
320                        UnaryOperator::Arithmetic(
321                            ArithmeticUnaryOperator::Plus,
322                        ) => value,
323                        UnaryOperator::Arithmetic(
324                            ArithmeticUnaryOperator::Minus,
325                        ) => value.neg().map_err(|_| ())?,
326                        _ => Err(())?,
327                    },
328                    _ => Err(())?,
329                }
330            }
331            DatexExpression::Null => ValueContainer::Value(Value::null()),
332            DatexExpression::Boolean(b) => ValueContainer::from(*b),
333            DatexExpression::Text(s) => ValueContainer::from(s.clone()),
334            DatexExpression::Decimal(d) => ValueContainer::from(d.clone()),
335            DatexExpression::Integer(i) => ValueContainer::from(i.clone()),
336            DatexExpression::Endpoint(e) => ValueContainer::from(e.clone()),
337            DatexExpression::List(arr) => {
338                let entries = arr
339                    .iter()
340                    .map(ValueContainer::try_from)
341                    .collect::<Result<Vec<ValueContainer>, ()>>()?;
342                ValueContainer::from(List::from(entries))
343            }
344            DatexExpression::Map(pairs) => {
345                let entries = pairs
346                    .iter()
347                    .map(|(k, v)| {
348                        let key = ValueContainer::try_from(k)?;
349                        let value = ValueContainer::try_from(v)?;
350                        Ok((key, value))
351                    })
352                    .collect::<Result<Vec<(ValueContainer, ValueContainer)>, ()>>()?;
353                ValueContainer::from(Map::from(entries))
354            }
355            _ => Err(())?,
356        })
357    }
358}
359
360pub struct DatexParseResult {
361    pub expression: DatexExpression,
362    pub is_static_value: bool,
363}
364
365pub fn create_parser<'a, T>()
366-> impl DatexParserTrait<'a, DatexExpression, Token>
367where
368    T: std::cmp::PartialEq + 'a,
369{
370    // an expression
371    let mut inner_expression = Recursive::declare();
372
373    // an expression or remote execution
374    let mut expression = Recursive::declare();
375
376    // a sequence of expressions, separated by semicolons, optionally terminated with a semicolon
377    let statements = expression
378        .clone()
379        .then_ignore(
380            just(Token::Semicolon)
381                .padded_by(whitespace())
382                .repeated()
383                .at_least(1),
384        )
385        .repeated()
386        .collect::<Vec<_>>()
387        .then(
388            expression
389                .clone()
390                .then(just(Token::Semicolon).padded_by(whitespace()).or_not())
391                .or_not(), // Final expression with optional semicolon
392        )
393        .map(|(exprs, last)| {
394            // Convert expressions with mandatory semicolon
395            let mut statements: Vec<Statement> = exprs
396                .into_iter()
397                .map(|expr| Statement {
398                    expression: expr,
399                    is_terminated: true,
400                })
401                .collect();
402
403            if let Some((last_expr, last_semi)) = last {
404                // If there's a last expression, add it as a statement
405                statements.push(Statement {
406                    expression: last_expr,
407                    is_terminated: last_semi.is_some(),
408                });
409            }
410            // if single statement without semicolon, treat it as a single expression
411            if statements.len() == 1 && !statements[0].is_terminated {
412                statements.remove(0).expression
413            } else {
414                DatexExpression::Statements(statements)
415            }
416        })
417        .boxed()
418        .labelled(Pattern::Custom("statements"));
419
420    // expression wrapped in parentheses
421    let wrapped_expression = statements
422        .clone()
423        .delimited_by(just(Token::LeftParen), just(Token::RightParen));
424    //.labelled(Pattern::Custom("wrapped"))
425    //.as_context();
426
427    // a valid map/list key
428    /// abc, a, "1", "test", (1 + 2), ...
429    let key = key(wrapped_expression.clone()).labelled(Pattern::Custom("key"));
430
431    // list
432    // 1,2,3
433    // [1,2,3,4,13434,(1),4,5,7,8]
434    let list = list(expression.clone());
435
436    // map
437    let map = map(key.clone(), expression.clone());
438
439    // atomic expression (e.g. 1, "text", (1 + 2), (1;2))
440    let atom = atom(list.clone(), map.clone(), wrapped_expression.clone());
441    let unary = unary(atom.clone());
442
443    // apply chain: two expressions following each other directly, optionally separated with "." (property access)
444    let chain =
445        chain(unary.clone(), key.clone(), atom.clone(), expression.clone());
446
447    let binary = binary_operation(chain);
448
449    // FIXME #363 WIP
450    let function_declaration = function(statements.clone());
451
452    // comparison (==, !=, is, …)
453    let comparison = comparison_operation(binary.clone());
454
455    // declarations or assignments
456    let declaration_or_assignment =
457        declaration_or_assignment(expression.clone(), unary.clone());
458
459    let condition_union = binary_operation(chain_without_whitespace_apply(
460        unary.clone(),
461        key.clone(),
462        expression.clone(),
463    ));
464    let condition = comparison_operation(condition_union);
465
466    let if_expression = recursive(|if_rec| {
467        just(Token::If)
468            .padded_by(whitespace())
469            .ignore_then(condition.clone())
470            .then(
471                choice((
472                    wrapped_expression.clone(),
473                    list.clone(),
474                    map.clone(),
475                    statements.clone(),
476                    unary.clone(),
477                ))
478                .padded_by(whitespace()),
479            )
480            .then(
481                just(Token::Else)
482                    .padded_by(whitespace())
483                    .ignore_then(choice((
484                        if_rec.clone(),
485                        wrapped_expression.clone(),
486                        list.clone(),
487                        map.clone(),
488                        statements.clone(),
489                        unary.clone(),
490                    )))
491                    .or_not(),
492            )
493            .map(|((cond, then_branch), else_opt)| {
494                DatexExpression::Conditional {
495                    condition: Box::new(cond),
496                    then_branch: Box::new(unwrap_single_statement(then_branch)),
497                    else_branch: else_opt
498                        .map(unwrap_single_statement)
499                        .map(Box::new),
500                }
501            })
502            .boxed()
503    });
504
505    // expression :: expression
506    let remote_execution = inner_expression
507        .clone()
508        .then_ignore(just(Token::DoubleColon).padded_by(whitespace()))
509        .then(inner_expression.clone())
510        .map(|(endpoint, expr)| {
511            DatexExpression::RemoteExecution(Box::new(endpoint), Box::new(expr))
512        });
513
514    inner_expression.define(
515        choice((
516            type_expression(),
517            if_expression,
518            declaration_or_assignment,
519            function_declaration,
520            comparison,
521        ))
522        .padded_by(whitespace()),
523    );
524
525    expression.define(choice((remote_execution, inner_expression.clone())));
526
527    choice((
528        // empty script (0-n semicolons)
529        just(Token::Semicolon)
530            .repeated()
531            .at_least(1)
532            .padded_by(whitespace())
533            .map(|_| DatexExpression::Statements(vec![])),
534        // statements
535        statements,
536    ))
537}
538
539pub fn parse(mut src: &str) -> Result<DatexExpression, Vec<ParseError>> {
540    // strip shebang at beginning of the source code
541    if src.starts_with("#!") {
542        if let Some(pos) = src.find('\n') {
543            src = &src[pos + 1..];
544        } else {
545            src = "";
546        }
547    }
548
549    let tokens = Token::lexer(src);
550    let tokens_spanned: Vec<(Token, Range<usize>)> = tokens
551        .spanned()
552        .map(|(tok, span)| {
553            tok.map(|t| (t, span.clone()))
554                .map_err(|_| ParseError::new_unexpected_with_span(None, span))
555        })
556        .collect::<Result<_, _>>()
557        .map_err(|e| vec![e])?;
558
559    let (tokens, spans): (Vec<_>, Vec<_>) = tokens_spanned.into_iter().unzip();
560    let parser = create_parser::<'_, Token>();
561    parser.parse(&tokens).into_result().map_err(|err| {
562        err.into_iter()
563            .map(|e| {
564                let mut owned_error: ParseError = e.clone();
565                let mut index = owned_error.token_pos().unwrap();
566                if index >= spans.len() {
567                    // FIXME #364 how to show file end?
568                    index = spans.len() - 1;
569                }
570                let span = spans.get(index).unwrap();
571                owned_error.set_span(span.clone());
572                owned_error
573            })
574            .collect()
575    })
576}
577
578#[cfg(test)]
579mod tests {
580    use crate::{
581        ast::error::{error::ErrorKind, pattern::Pattern, src::SrcId},
582        values::core_values::endpoint::InvalidEndpointError,
583    };
584
585    use super::*;
586    use std::{
587        assert_matches::assert_matches, collections::HashMap, io, str::FromStr,
588        vec,
589    };
590
591    fn parse_unwrap(src: &str) -> DatexExpression {
592        let src_id = SrcId::test();
593        let res = parse(src);
594        if let Err(errors) = res {
595            errors.iter().for_each(|e| {
596                let cache = ariadne::sources(vec![(src_id, src)]);
597                e.clone().write(cache, io::stdout());
598            });
599            panic!("Parsing errors found");
600        }
601        res.unwrap()
602    }
603
604    fn parse_print_error(
605        src: &str,
606    ) -> Result<DatexExpression, Vec<ParseError>> {
607        let src_id = SrcId::test();
608        let res = parse(src);
609        if let Err(errors) = &res {
610            errors.iter().for_each(|e| {
611                let cache = ariadne::sources(vec![(src_id, src)]);
612                e.clone().write(cache, io::stdout());
613            });
614        }
615        res
616    }
617
618    fn try_parse_to_value_container(src: &str) -> ValueContainer {
619        let expr = parse_unwrap(src);
620        ValueContainer::try_from(&expr).unwrap_or_else(|_| {
621            panic!("Failed to convert expression to ValueContainer")
622        })
623    }
624
625    #[test]
626    fn json() {
627        let src = r#"
628            {
629                "name": "Test",
630                "value": 42,
631                "active": true,
632                "items": [1, 2, 3, 0.5],
633                "nested": {
634                    "key": "value"
635                }
636            }
637        "#;
638
639        let json = parse_unwrap(src);
640
641        assert_eq!(
642            json,
643            DatexExpression::Map(vec![
644                (
645                    DatexExpression::Text("name".to_string()),
646                    DatexExpression::Text("Test".to_string())
647                ),
648                (
649                    DatexExpression::Text("value".to_string()),
650                    DatexExpression::Integer(Integer::from(42))
651                ),
652                (
653                    DatexExpression::Text("active".to_string()),
654                    DatexExpression::Boolean(true)
655                ),
656                (
657                    DatexExpression::Text("items".to_string()),
658                    DatexExpression::List(vec![
659                        DatexExpression::Integer(Integer::from(1)),
660                        DatexExpression::Integer(Integer::from(2)),
661                        DatexExpression::Integer(Integer::from(3)),
662                        DatexExpression::Decimal(
663                            Decimal::from_string("0.5").unwrap()
664                        )
665                    ])
666                ),
667                (
668                    DatexExpression::Text("nested".to_string()),
669                    DatexExpression::Map(
670                        vec![(
671                            DatexExpression::Text("key".to_string()),
672                            DatexExpression::Text("value".to_string())
673                        )]
674                        .into_iter()
675                        .collect()
676                    )
677                ),
678            ])
679        );
680    }
681
682    #[test]
683    #[ignore = "WIP"]
684    fn type_expression() {
685        let src = "type(1 | 2)";
686        let result = parse_print_error(src);
687        let expr = result.unwrap();
688        assert_matches!(expr, DatexExpression::Type(TypeExpression::Union(_)));
689
690        let src = "var a = type(1,2,3)";
691        let result = parse_print_error(src);
692        let expr = result.unwrap();
693        if let DatexExpression::VariableDeclaration {
694            init_expression: value,
695            ..
696        } = expr
697        {
698            assert_matches!(
699                *value,
700                DatexExpression::Type(TypeExpression::StructuralList(_))
701            );
702        } else {
703            panic!("Expected VariableDeclaration");
704        }
705    }
706
707    #[test]
708    fn structural_type_declaration() {
709        let src = "typedef A = integer";
710        let result = parse_print_error(src);
711        let expr = result.unwrap();
712        assert_matches!(expr, DatexExpression::TypeDeclaration { name, .. } if name == "A");
713    }
714
715    #[test]
716    fn nominal_type_declaration() {
717        let src = "type B = { x: integer, y: string }";
718        let result = parse_print_error(src);
719        let expr = result.unwrap();
720        assert_matches!(expr, DatexExpression::TypeDeclaration { name, .. } if name == "B");
721
722        let src = "type User<T> = {id: T}";
723        let result = parse_print_error(src);
724        let expr = result.unwrap();
725        assert_matches!(expr, DatexExpression::TypeDeclaration { name, .. } if name == "User");
726
727        let src = "type User/admin = {id: integer}";
728        let result = parse_print_error(src);
729        let expr = result.unwrap();
730        assert_matches!(expr, DatexExpression::TypeDeclaration { name, .. } if name == "User/admin");
731    }
732
733    /// # WIP
734    /// This test is a WIP item, that should allow us to provide context to the grammar error recovery.
735    #[test]
736    #[ignore = "WIP"]
737    fn test_parse_error_unclosed_delimiter() {
738        let src = r#"[1,,]"#;
739        let result = parse_print_error(src);
740
741        let src = r#"var x"#;
742        let result = parse_print_error(src);
743
744        let src = r#"var x = =1"#;
745        let result = parse_print_error(src);
746
747        let src = r#"var x = (1, 2, [10, 20, {1:2})] + 4"#;
748        let result = parse_print_error(src);
749
750        let src = r#"[1, )]"#;
751        let result = parse_print_error(src);
752
753        let src = r#"(1 + 2 + ])"#;
754        let result = parse_print_error(src);
755
756        let src = r#"{x: 1 + +}"#;
757        let result = parse_print_error(src);
758
759        let src = r#"(1: x, 2: 1 + +)"#;
760        let result = parse_print_error(src);
761
762        // let src = r#"
763        // var x = (5 + 3;
764        // var y = 42;
765        // "#;
766        // let result = parse_print_error(src);
767        // println!("{:?}", result);
768        // let errors = result.err().unwrap();
769        // assert_eq!(errors.len(), 3);
770        // let error1 = errors[0].clone();
771        // assert_matches!(
772        //     error1.kind(),
773        //     ErrorKind::Unexpected {
774        //         found: None,
775        //         expected: _,
776        //     }
777        // );
778        // assert_eq!(error1.span(), Some(17..18));
779        // let error2 = errors[1].clone();
780        // assert_matches!(
781        //     error2.kind(),
782        //     ErrorKind::Unexpected {
783        //         found: None,
784        //         expected: _,
785        //     }
786        // );
787        // assert_eq!(error2.span(), Some(45..46));
788        // let error3 = errors[2].clone();
789        // assert_matches!(
790        //     error3.kind(),
791        //     ErrorKind::Unexpected {
792        //         found: None,
793        //         expected: _,
794        //     }
795        // );
796        // assert_eq!(error3.span(), Some(73..74));
797    }
798
799    #[test]
800    fn parse_error_endpoint() {
801        let src = "@j0Onas";
802        let result = parse_print_error(src);
803        let errors = result.err().unwrap();
804        assert_eq!(errors.len(), 1);
805        let error = errors[0].clone();
806        assert_matches!(
807            error.kind(),
808            ErrorKind::InvalidEndpoint(InvalidEndpointError::InvalidCharacters)
809        );
810        assert_eq!(error.span(), Some(0..7));
811    }
812
813    #[test]
814    fn parse_error_missing_token() {
815        let src = r#"
816        var x = 52; var y = ; 
817        var y = 5
818        "#;
819        let result = parse_print_error(src);
820        let errors = result.err().unwrap();
821        assert_eq!(errors.len(), 1);
822        let error = errors[0].clone();
823        assert_matches!(
824            error.kind(),
825            ErrorKind::Unexpected {
826                found: Some(Pattern::Token(Token::Semicolon)),
827                ..
828            }
829        );
830        assert_eq!(error.span(), Some(29..30));
831    }
832
833    #[test]
834    fn parse_error_multiple() {
835        let src = r#"
836        var x = @j0Onas;
837        var z = 10;
838        var y = @b0Onas;
839        "#;
840        let result = parse_print_error(src);
841        let errors = result.err().unwrap();
842        assert_eq!(errors.len(), 2);
843        let error1 = errors[0].clone();
844        assert_matches!(
845            error1.kind(),
846            ErrorKind::InvalidEndpoint(InvalidEndpointError::InvalidCharacters)
847        );
848        assert_eq!(error1.span(), Some(17..24));
849        let error2 = errors[1].clone();
850        assert_matches!(
851            error2.kind(),
852            ErrorKind::InvalidEndpoint(InvalidEndpointError::InvalidCharacters)
853        );
854        assert_eq!(error2.span(), Some(62..69));
855    }
856
857    #[test]
858    fn parse_error_invalid_declaration() {
859        let src = "var x = 10; const x += 5;";
860        let result = parse_print_error(src);
861        let errors = result.err().unwrap();
862        assert_eq!(errors.len(), 1);
863        let error = errors[0].clone();
864        assert_eq!(
865            error.message(),
866            "Cannot use '+=' operator in variable declaration"
867        );
868        assert_eq!(error.span(), Some(12..17));
869    }
870
871    #[test]
872    fn parse_error_u8() {
873        let src = "var x = 256u8;";
874        let result = parse_print_error(src);
875        let errors = result.err().unwrap();
876        assert_eq!(errors.len(), 1);
877        let error = errors[0].clone();
878        assert_eq!(
879            error.message(),
880            "The number is out of range for the specified type."
881        );
882        assert_eq!(error.span(), Some(8..13));
883    }
884
885    #[test]
886    fn parse_error_typed_decimal() {
887        let src: &'static str =
888            "var x = 10000000000000000000000000000000000000000000000000.3f32";
889        let result = parse_print_error(src);
890
891        let errors = result.err().unwrap();
892        assert_eq!(errors.len(), 1);
893        let error = errors[0].clone();
894        assert_eq!(
895            error.message(),
896            "The number is out of range for the specified type."
897        );
898        assert_eq!(error.span(), Some(8..63));
899    }
900
901    #[test]
902    fn function_simple() {
903        let src = r#"
904            function myFunction() (
905                42
906            )
907        "#;
908        let val = parse_unwrap(src);
909        assert_eq!(
910            val,
911            DatexExpression::FunctionDeclaration {
912                name: "myFunction".to_string(),
913                parameters: Vec::new(),
914                return_type: None,
915                body: Box::new(DatexExpression::Integer(Integer::from(42))),
916            }
917        );
918    }
919
920    #[test]
921    fn function_with_params() {
922        let src = r#"
923            function myFunction(x: integer) (
924                42
925            )
926        "#;
927        let val = parse_unwrap(src);
928        assert_eq!(
929            val,
930            DatexExpression::FunctionDeclaration {
931                name: "myFunction".to_string(),
932                parameters: vec![(
933                    "x".to_string(),
934                    TypeExpression::Literal("integer".to_owned())
935                )],
936                return_type: None,
937                body: Box::new(DatexExpression::Integer(Integer::from(42))),
938            }
939        );
940
941        let src = r#"
942            function myFunction(x: integer, y: integer) (
943                1 + 2;
944            )
945        "#;
946        let val = parse_unwrap(src);
947        assert_eq!(
948            val,
949            DatexExpression::FunctionDeclaration {
950                name: "myFunction".to_string(),
951                parameters: vec![
952                    (
953                        "x".to_string(),
954                        TypeExpression::Literal("integer".to_owned())
955                    ),
956                    (
957                        "y".to_string(),
958                        TypeExpression::Literal("integer".to_owned())
959                    )
960                ],
961                return_type: None,
962                body: Box::new(DatexExpression::Statements(vec![Statement {
963                    expression: DatexExpression::BinaryOperation(
964                        BinaryOperator::Arithmetic(ArithmeticOperator::Add),
965                        Box::new(DatexExpression::Integer(Integer::from(1))),
966                        Box::new(DatexExpression::Integer(Integer::from(2))),
967                        None
968                    ),
969                    is_terminated: true
970                }])),
971            }
972        );
973    }
974
975    #[test]
976    fn test_function_with_return_type() {
977        let src = r#"
978            function myFunction(x: integer) -> integer | text (
979                42
980            )
981        "#;
982        let val = parse_unwrap(src);
983        assert_eq!(
984            val,
985            DatexExpression::FunctionDeclaration {
986                name: "myFunction".to_string(),
987                parameters: vec![(
988                    "x".to_string(),
989                    TypeExpression::Literal("integer".to_owned())
990                ),],
991                return_type: Some(TypeExpression::Union(vec![
992                    TypeExpression::Literal("integer".to_owned()),
993                    TypeExpression::Literal("text".to_owned())
994                ])),
995                body: Box::new(DatexExpression::Integer(Integer::from(42))),
996            }
997        );
998    }
999
1000    #[test]
1001    fn type_var_declaration() {
1002        let src = "var x: 5 = 42";
1003        let val = parse_unwrap(src);
1004        assert_eq!(
1005            val,
1006            DatexExpression::VariableDeclaration {
1007                id: None,
1008                kind: VariableKind::Var,
1009                type_annotation: Some(
1010                    TypeExpression::Integer(Integer::from(5)).into()
1011                ),
1012                name: "x".to_string(),
1013                init_expression: Box::new(DatexExpression::Integer(
1014                    Integer::from(42)
1015                ))
1016            }
1017        );
1018
1019        let src = "var x: integer/u8 = 42";
1020        let val = parse_unwrap(src);
1021        assert_eq!(
1022            val,
1023            DatexExpression::VariableDeclaration {
1024                id: None,
1025                kind: VariableKind::Var,
1026                type_annotation: Some(TypeExpression::Literal(
1027                    "integer/u8".to_owned()
1028                )),
1029                name: "x".to_string(),
1030                init_expression: Box::new(DatexExpression::Integer(
1031                    Integer::from(42)
1032                ))
1033            }
1034        );
1035    }
1036
1037    #[deprecated(note = "Remove intersection from value syntax")]
1038    #[test]
1039    fn intersection() {
1040        let src = "5 & 6";
1041        let val = parse_unwrap(src);
1042        assert_eq!(
1043            val,
1044            DatexExpression::BinaryOperation(
1045                BinaryOperator::Bitwise(BitwiseOperator::And),
1046                Box::new(DatexExpression::Integer(Integer::from(5))),
1047                Box::new(DatexExpression::Integer(Integer::from(6))),
1048                None
1049            )
1050        );
1051
1052        let src = "(integer/u8 & 6) & 2";
1053        let val = parse_unwrap(src);
1054        assert_eq!(
1055            val,
1056            DatexExpression::BinaryOperation(
1057                BinaryOperator::Bitwise(BitwiseOperator::And),
1058                Box::new(DatexExpression::BinaryOperation(
1059                    BinaryOperator::Bitwise(BitwiseOperator::And),
1060                    Box::new(DatexExpression::BinaryOperation(
1061                        BinaryOperator::VariantAccess,
1062                        Box::new(DatexExpression::Identifier(
1063                            "integer".to_owned()
1064                        )),
1065                        Box::new(DatexExpression::Identifier("u8".to_owned())),
1066                        None
1067                    )),
1068                    Box::new(DatexExpression::Integer(Integer::from(6))),
1069                    None
1070                )),
1071                Box::new(DatexExpression::Integer(Integer::from(2))),
1072                None
1073            )
1074        );
1075    }
1076
1077    #[deprecated(note = "Remove union from value syntax")]
1078    #[test]
1079    fn union() {
1080        let src = "5 | 6";
1081        let val = parse_unwrap(src);
1082        assert_eq!(
1083            val,
1084            DatexExpression::BinaryOperation(
1085                BinaryOperator::Bitwise(BitwiseOperator::Or),
1086                Box::new(DatexExpression::Integer(Integer::from(5))),
1087                Box::new(DatexExpression::Integer(Integer::from(6))),
1088                None
1089            )
1090        );
1091
1092        let src = "(integer/u8 | 6) | 2";
1093        let val = parse_unwrap(src);
1094        assert_eq!(
1095            val,
1096            DatexExpression::BinaryOperation(
1097                BinaryOperator::Bitwise(BitwiseOperator::Or),
1098                Box::new(DatexExpression::BinaryOperation(
1099                    BinaryOperator::Bitwise(BitwiseOperator::Or),
1100                    Box::new(DatexExpression::BinaryOperation(
1101                        BinaryOperator::VariantAccess,
1102                        Box::new(DatexExpression::Identifier(
1103                            "integer".to_owned()
1104                        )),
1105                        Box::new(DatexExpression::Identifier("u8".to_owned())),
1106                        None
1107                    )),
1108                    Box::new(DatexExpression::Integer(Integer::from(6))),
1109                    None
1110                )),
1111                Box::new(DatexExpression::Integer(Integer::from(2))),
1112                None
1113            )
1114        );
1115    }
1116
1117    #[test]
1118    fn binary_operator_precedence() {
1119        let src = "1 + 2 * 3";
1120        let val = parse_unwrap(src);
1121        assert_eq!(
1122            val,
1123            DatexExpression::BinaryOperation(
1124                BinaryOperator::Arithmetic(ArithmeticOperator::Add),
1125                Box::new(DatexExpression::Integer(Integer::from(1))),
1126                Box::new(DatexExpression::BinaryOperation(
1127                    BinaryOperator::Arithmetic(ArithmeticOperator::Multiply),
1128                    Box::new(DatexExpression::Integer(Integer::from(2))),
1129                    Box::new(DatexExpression::Integer(Integer::from(3))),
1130                    None
1131                )),
1132                None
1133            )
1134        );
1135
1136        let src = "1 + 2 & 3";
1137        let val = parse_unwrap(src);
1138        assert_eq!(
1139            val,
1140            DatexExpression::BinaryOperation(
1141                BinaryOperator::Bitwise(BitwiseOperator::And),
1142                Box::new(DatexExpression::BinaryOperation(
1143                    BinaryOperator::Arithmetic(ArithmeticOperator::Add),
1144                    Box::new(DatexExpression::Integer(Integer::from(1))),
1145                    Box::new(DatexExpression::Integer(Integer::from(2))),
1146                    None
1147                )),
1148                Box::new(DatexExpression::Integer(Integer::from(3))),
1149                None
1150            )
1151        );
1152
1153        let src = "1 + 2 | 3";
1154        let val = parse_unwrap(src);
1155        assert_eq!(
1156            val,
1157            DatexExpression::BinaryOperation(
1158                BinaryOperator::Bitwise(BitwiseOperator::Or),
1159                Box::new(DatexExpression::BinaryOperation(
1160                    BinaryOperator::Arithmetic(ArithmeticOperator::Add),
1161                    Box::new(DatexExpression::Integer(Integer::from(1))),
1162                    Box::new(DatexExpression::Integer(Integer::from(2))),
1163                    None
1164                )),
1165                Box::new(DatexExpression::Integer(Integer::from(3))),
1166                None
1167            )
1168        );
1169    }
1170
1171    #[test]
1172    fn generic_assessor() {
1173        let expected = DatexExpression::ApplyChain(
1174            Box::new(DatexExpression::Identifier("User".to_string())),
1175            vec![
1176                ApplyOperation::GenericAccess(
1177                    DatexExpression::BinaryOperation(
1178                        BinaryOperator::VariantAccess,
1179                        Box::new(DatexExpression::Identifier(
1180                            "integer".to_owned(),
1181                        )),
1182                        Box::new(DatexExpression::Identifier("u8".to_owned())),
1183                        None,
1184                    ),
1185                ),
1186                ApplyOperation::FunctionCall(DatexExpression::Map(vec![])),
1187            ],
1188        );
1189        assert_eq!(parse_unwrap("User<integer/u8> {}"), expected);
1190        assert_eq!(parse_unwrap("User< integer/u8 > {}"), expected);
1191        assert_eq!(parse_unwrap("User<integer/u8 > {}"), expected);
1192        assert!(parse("User <integer/u8> {}").is_err());
1193    }
1194
1195    #[test]
1196    fn if_else() {
1197        let src = vec![
1198            "if true (1) else (2)",
1199            "if true 1 else 2",
1200            "if (true) (1) else (2)",
1201            "if (true) 1 else 2",
1202            "if true (1) else 2",
1203            "if (true) 1 else (2)",
1204            "if true 1 else (2)",
1205        ];
1206        for s in src {
1207            let val = parse_unwrap(s);
1208            assert_eq!(
1209                val,
1210                DatexExpression::Conditional {
1211                    condition: Box::new(DatexExpression::Boolean(true)),
1212                    then_branch: Box::new(DatexExpression::Integer(
1213                        Integer::from(1)
1214                    )),
1215                    else_branch: Some(Box::new(DatexExpression::Integer(
1216                        Integer::from(2)
1217                    ))),
1218                }
1219            );
1220        }
1221
1222        let src = vec![
1223            "if true + 1 == 2 (4) else 2",
1224            "if (true + 1) == 2 4 else 2",
1225            "if true + 1 == 2 (4) else (2)",
1226            "if (true + 1) == 2 (4) else (2)",
1227            "if true + 1 == 2 (4) else 2",
1228            "if (true + 1) == 2 4 else (2)",
1229        ];
1230        for s in src {
1231            println!("{}", s);
1232            let val = parse_unwrap(s);
1233            assert_eq!(
1234                val,
1235                DatexExpression::Conditional {
1236                    condition: Box::new(DatexExpression::ComparisonOperation(
1237                        ComparisonOperator::StructuralEqual,
1238                        Box::new(DatexExpression::BinaryOperation(
1239                            BinaryOperator::Arithmetic(ArithmeticOperator::Add),
1240                            Box::new(DatexExpression::Boolean(true)),
1241                            Box::new(DatexExpression::Integer(Integer::from(
1242                                1
1243                            ))),
1244                            None
1245                        )),
1246                        Box::new(DatexExpression::Integer(Integer::from(2)))
1247                    )),
1248                    then_branch: Box::new(DatexExpression::Integer(
1249                        Integer::from(4)
1250                    )),
1251                    else_branch: Some(Box::new(DatexExpression::Integer(
1252                        Integer::from(2)
1253                    ))),
1254                }
1255            );
1256        }
1257
1258        // make sure apply chains still work
1259        let src = vec![
1260            "if true + 1 == 2 test [1,2,3]",
1261            "if true + 1 == 2 (test [1,2,3])",
1262        ];
1263        for s in src {
1264            let val = parse_unwrap(s);
1265            assert_eq!(
1266                val,
1267                DatexExpression::Conditional {
1268                    condition: Box::new(DatexExpression::ComparisonOperation(
1269                        ComparisonOperator::StructuralEqual,
1270                        Box::new(DatexExpression::BinaryOperation(
1271                            BinaryOperator::Arithmetic(ArithmeticOperator::Add),
1272                            Box::new(DatexExpression::Boolean(true)),
1273                            Box::new(DatexExpression::Integer(Integer::from(
1274                                1
1275                            ))),
1276                            None
1277                        )),
1278                        Box::new(DatexExpression::Integer(Integer::from(2)))
1279                    )),
1280                    then_branch: Box::new(DatexExpression::ApplyChain(
1281                        Box::new(DatexExpression::Identifier(
1282                            "test".to_string()
1283                        )),
1284                        vec![ApplyOperation::FunctionCall(
1285                            DatexExpression::List(vec![
1286                                DatexExpression::Integer(Integer::from(1)),
1287                                DatexExpression::Integer(Integer::from(2)),
1288                                DatexExpression::Integer(Integer::from(3)),
1289                            ])
1290                        )]
1291                    )),
1292                    else_branch: None,
1293                }
1294            );
1295        }
1296    }
1297
1298    #[test]
1299    fn if_else_if_else() {
1300        let src = r#"
1301            if x == 4 (
1302                "4"
1303            ) else if x == 'hello' (
1304                "42" 
1305            ) else null;
1306        "#;
1307
1308        let val = parse_unwrap(src);
1309        assert_eq!(
1310            val,
1311            DatexExpression::Conditional {
1312                condition: Box::new(DatexExpression::ComparisonOperation(
1313                    ComparisonOperator::StructuralEqual,
1314                    Box::new(DatexExpression::Identifier("x".to_string())),
1315                    Box::new(DatexExpression::Integer(Integer::from(4)))
1316                )),
1317                then_branch: Box::new(DatexExpression::Text("4".to_string())),
1318                else_branch: Some(Box::new(DatexExpression::Conditional {
1319                    condition: Box::new(DatexExpression::ComparisonOperation(
1320                        ComparisonOperator::StructuralEqual,
1321                        Box::new(DatexExpression::Identifier("x".to_string())),
1322                        Box::new(DatexExpression::Text("hello".to_string()))
1323                    )),
1324                    then_branch: Box::new(DatexExpression::Text(
1325                        "42".to_string()
1326                    )),
1327                    else_branch: Some(Box::new(DatexExpression::Null))
1328                })),
1329            }
1330        );
1331    }
1332
1333    #[test]
1334    fn unary_operator() {
1335        let src = "+(User {})";
1336        let val = parse_unwrap(src);
1337        assert_eq!(
1338            val,
1339            DatexExpression::UnaryOperation(
1340                UnaryOperator::Arithmetic(ArithmeticUnaryOperator::Plus),
1341                Box::new(DatexExpression::ApplyChain(
1342                    Box::new(DatexExpression::Identifier("User".to_string())),
1343                    vec![ApplyOperation::FunctionCall(DatexExpression::Map(
1344                        vec![]
1345                    ))]
1346                )),
1347            )
1348        );
1349
1350        let src = "-(5)";
1351        let val = parse_unwrap(src);
1352        assert_eq!(
1353            val,
1354            DatexExpression::UnaryOperation(
1355                UnaryOperator::Arithmetic(ArithmeticUnaryOperator::Minus),
1356                Box::new(DatexExpression::Integer(Integer::from(5)))
1357            )
1358        );
1359
1360        let src = "+-+-myVal";
1361        let val = parse_unwrap(src);
1362        assert_eq!(
1363            val,
1364            DatexExpression::UnaryOperation(
1365                UnaryOperator::Arithmetic(ArithmeticUnaryOperator::Plus),
1366                Box::new(DatexExpression::UnaryOperation(
1367                    UnaryOperator::Arithmetic(ArithmeticUnaryOperator::Minus),
1368                    Box::new(DatexExpression::UnaryOperation(
1369                        UnaryOperator::Arithmetic(
1370                            ArithmeticUnaryOperator::Plus
1371                        ),
1372                        Box::new(DatexExpression::UnaryOperation(
1373                            UnaryOperator::Arithmetic(
1374                                ArithmeticUnaryOperator::Minus
1375                            ),
1376                            Box::new(DatexExpression::Identifier(
1377                                "myVal".to_string()
1378                            ))
1379                        ))
1380                    ))
1381                ))
1382            )
1383        );
1384    }
1385
1386    #[test]
1387    fn var_declaration_with_type_simple() {
1388        let src = "var x: integer = 42";
1389        let val = parse_unwrap(src);
1390        assert_eq!(
1391            val,
1392            DatexExpression::VariableDeclaration {
1393                id: None,
1394                kind: VariableKind::Var,
1395                type_annotation: Some(TypeExpression::Literal(
1396                    "integer".to_string()
1397                )),
1398                name: "x".to_string(),
1399                init_expression: Box::new(DatexExpression::Integer(
1400                    Integer::from(42)
1401                ))
1402            }
1403        );
1404
1405        let src = "var x: User = 42";
1406        let val = parse_unwrap(src);
1407        assert_eq!(
1408            val,
1409            DatexExpression::VariableDeclaration {
1410                id: None,
1411                kind: VariableKind::Var,
1412                type_annotation: Some(TypeExpression::Literal(
1413                    "User".to_string()
1414                )),
1415                name: "x".to_string(),
1416                init_expression: Box::new(DatexExpression::Integer(
1417                    Integer::from(42)
1418                ))
1419            }
1420        );
1421
1422        let src = "var x: integer/u8 = 42";
1423        let val = parse_unwrap(src);
1424        assert_eq!(
1425            val,
1426            DatexExpression::VariableDeclaration {
1427                id: None,
1428                kind: VariableKind::Var,
1429                type_annotation: Some(TypeExpression::Literal(
1430                    "integer/u8".to_owned()
1431                )),
1432                name: "x".to_string(),
1433                init_expression: Box::new(DatexExpression::Integer(
1434                    Integer::from(42)
1435                ))
1436            }
1437        );
1438    }
1439
1440    #[test]
1441    fn var_declaration_with_type_union() {
1442        let src = "var x: integer/u8 | text = 42";
1443        let val = parse_unwrap(src);
1444        assert_eq!(
1445            val,
1446            DatexExpression::VariableDeclaration {
1447                id: None,
1448                kind: VariableKind::Var,
1449                type_annotation: Some(TypeExpression::Union(vec![
1450                    TypeExpression::Literal("integer/u8".to_owned()),
1451                    TypeExpression::Literal("text".to_owned())
1452                ])),
1453                name: "x".to_string(),
1454                init_expression: Box::new(DatexExpression::Integer(
1455                    Integer::from(42)
1456                ))
1457            }
1458        );
1459    }
1460
1461    #[test]
1462    fn var_declaration_with_type_intersection() {
1463        let src = "var x: 5 & 6 = 42";
1464        let val = parse_unwrap(src);
1465        assert_eq!(
1466            val,
1467            DatexExpression::VariableDeclaration {
1468                id: None,
1469                kind: VariableKind::Var,
1470                type_annotation: Some(TypeExpression::Intersection(vec![
1471                    TypeExpression::Integer(Integer::from(5)),
1472                    TypeExpression::Integer(Integer::from(6))
1473                ])),
1474                name: "x".to_string(),
1475                init_expression: Box::new(DatexExpression::Integer(
1476                    Integer::from(42)
1477                ))
1478            }
1479        );
1480    }
1481
1482    #[test]
1483    fn test_type_var_declaration_list() {
1484        let src = "var x: integer[] = 42";
1485        let val = parse_unwrap(src);
1486        assert_eq!(
1487            val,
1488            DatexExpression::VariableDeclaration {
1489                id: None,
1490                kind: VariableKind::Var,
1491                type_annotation: Some(TypeExpression::SliceList(Box::new(
1492                    TypeExpression::Literal("integer".to_owned())
1493                ))),
1494                name: "x".to_string(),
1495                init_expression: Box::new(DatexExpression::Integer(
1496                    Integer::from(42)
1497                ))
1498            }
1499        );
1500    }
1501
1502    #[test]
1503    fn equal_operators() {
1504        let src = "3 == 1 + 2";
1505        let val = parse_unwrap(src);
1506        assert_eq!(
1507            val,
1508            DatexExpression::ComparisonOperation(
1509                ComparisonOperator::StructuralEqual,
1510                Box::new(DatexExpression::Integer(Integer::from(3))),
1511                Box::new(DatexExpression::BinaryOperation(
1512                    BinaryOperator::Arithmetic(ArithmeticOperator::Add),
1513                    Box::new(DatexExpression::Integer(Integer::from(1))),
1514                    Box::new(DatexExpression::Integer(Integer::from(2))),
1515                    None
1516                ))
1517            )
1518        );
1519
1520        let src = "3 === 1 + 2";
1521        let val = parse_unwrap(src);
1522        assert_eq!(
1523            val,
1524            DatexExpression::ComparisonOperation(
1525                ComparisonOperator::Equal,
1526                Box::new(DatexExpression::Integer(Integer::from(3))),
1527                Box::new(DatexExpression::BinaryOperation(
1528                    BinaryOperator::Arithmetic(ArithmeticOperator::Add),
1529                    Box::new(DatexExpression::Integer(Integer::from(1))),
1530                    Box::new(DatexExpression::Integer(Integer::from(2))),
1531                    None
1532                ))
1533            )
1534        );
1535
1536        let src = "5 != 1 + 2";
1537        let val = parse_unwrap(src);
1538        assert_eq!(
1539            val,
1540            DatexExpression::ComparisonOperation(
1541                ComparisonOperator::NotStructuralEqual,
1542                Box::new(DatexExpression::Integer(Integer::from(5))),
1543                Box::new(DatexExpression::BinaryOperation(
1544                    BinaryOperator::Arithmetic(ArithmeticOperator::Add),
1545                    Box::new(DatexExpression::Integer(Integer::from(1))),
1546                    Box::new(DatexExpression::Integer(Integer::from(2))),
1547                    None
1548                ))
1549            )
1550        );
1551        let src = "5 !== 1 + 2";
1552        let val = parse_unwrap(src);
1553        assert_eq!(
1554            val,
1555            DatexExpression::ComparisonOperation(
1556                ComparisonOperator::NotEqual,
1557                Box::new(DatexExpression::Integer(Integer::from(5))),
1558                Box::new(DatexExpression::BinaryOperation(
1559                    BinaryOperator::Arithmetic(ArithmeticOperator::Add),
1560                    Box::new(DatexExpression::Integer(Integer::from(1))),
1561                    Box::new(DatexExpression::Integer(Integer::from(2))),
1562                    None
1563                ))
1564            )
1565        );
1566
1567        let src = "5 is 1 + 2";
1568        let val = parse_unwrap(src);
1569        assert_eq!(
1570            val,
1571            DatexExpression::ComparisonOperation(
1572                ComparisonOperator::Is,
1573                Box::new(DatexExpression::Integer(Integer::from(5))),
1574                Box::new(DatexExpression::BinaryOperation(
1575                    BinaryOperator::Arithmetic(ArithmeticOperator::Add),
1576                    Box::new(DatexExpression::Integer(Integer::from(1))),
1577                    Box::new(DatexExpression::Integer(Integer::from(2))),
1578                    None
1579                ))
1580            )
1581        );
1582    }
1583
1584    #[test]
1585    fn null() {
1586        let src = "null";
1587        let val = parse_unwrap(src);
1588        assert_eq!(val, DatexExpression::Null);
1589    }
1590
1591    #[test]
1592    fn boolean() {
1593        let src_true = "true";
1594        let val_true = parse_unwrap(src_true);
1595        assert_eq!(val_true, DatexExpression::Boolean(true));
1596
1597        let src_false = "false";
1598        let val_false = parse_unwrap(src_false);
1599        assert_eq!(val_false, DatexExpression::Boolean(false));
1600    }
1601
1602    #[test]
1603    fn integer() {
1604        let src = "123456789123456789";
1605        let num = parse_unwrap(src);
1606        assert_eq!(
1607            num,
1608            DatexExpression::Integer(
1609                Integer::from_string("123456789123456789").unwrap()
1610            )
1611        );
1612    }
1613
1614    #[test]
1615    fn negative_integer() {
1616        let src = "-123456789123456789";
1617        let num = parse_unwrap(src);
1618        assert_eq!(
1619            num,
1620            DatexExpression::UnaryOperation(
1621                UnaryOperator::Arithmetic(ArithmeticUnaryOperator::Minus),
1622                Box::new(DatexExpression::Integer(
1623                    Integer::from_string("123456789123456789").unwrap()
1624                ))
1625            )
1626        );
1627    }
1628
1629    #[test]
1630    fn integer_with_underscores() {
1631        let src = "123_456";
1632        let num = parse_unwrap(src);
1633        assert_eq!(
1634            num,
1635            DatexExpression::Integer(Integer::from_string("123456").unwrap())
1636        );
1637    }
1638
1639    #[test]
1640    fn hex_integer() {
1641        let src = "0x1A2B3C4D5E6F";
1642        let num = parse_unwrap(src);
1643        assert_eq!(
1644            num,
1645            DatexExpression::Integer(
1646                Integer::from_string_radix("1A2B3C4D5E6F", 16).unwrap()
1647            )
1648        );
1649    }
1650
1651    #[test]
1652    fn octal_integer() {
1653        let src = "0o755";
1654        let num = parse_unwrap(src);
1655        assert_eq!(
1656            num,
1657            DatexExpression::Integer(
1658                Integer::from_string_radix("755", 8).unwrap()
1659            )
1660        );
1661    }
1662
1663    #[test]
1664    fn binary_integer() {
1665        let src = "0b101010";
1666        let num = parse_unwrap(src);
1667        assert_eq!(
1668            num,
1669            DatexExpression::Integer(
1670                Integer::from_string_radix("101010", 2).unwrap()
1671            )
1672        );
1673    }
1674
1675    #[test]
1676    fn integer_with_exponent() {
1677        let src = "2e10";
1678        let num = parse_unwrap(src);
1679        assert_eq!(
1680            num,
1681            DatexExpression::Decimal(
1682                Decimal::from_string("20000000000").unwrap()
1683            )
1684        );
1685    }
1686
1687    #[test]
1688    fn decimal() {
1689        let src = "123.456789123456";
1690        let num = parse_unwrap(src);
1691        assert_eq!(
1692            num,
1693            DatexExpression::Decimal(
1694                Decimal::from_string("123.456789123456").unwrap()
1695            )
1696        );
1697    }
1698
1699    #[test]
1700    fn decimal_with_separator() {
1701        let cases = [
1702            ("123_45_6.789", "123456.789"),
1703            ("123.443_3434", "123.4433434"),
1704            ("1_000.000_001", "1000.000001"),
1705            ("3.14_15e+1_0", "31415000000.0"),
1706            ("0.0_0_1", "0.001"),
1707            ("1_000.0", "1000.0"),
1708        ];
1709
1710        for (src, expected_str) in cases {
1711            let num = parse_unwrap(src);
1712            assert_eq!(
1713                num,
1714                DatexExpression::Decimal(
1715                    Decimal::from_string(expected_str).unwrap()
1716                ),
1717                "Failed to parse: {src}"
1718            );
1719        }
1720    }
1721
1722    #[test]
1723    fn negative_decimal() {
1724        let src = "-123.4";
1725        let num = parse_unwrap(src);
1726        assert_eq!(
1727            num,
1728            DatexExpression::UnaryOperation(
1729                UnaryOperator::Arithmetic(ArithmeticUnaryOperator::Minus),
1730                Box::new(DatexExpression::Decimal(
1731                    Decimal::from_string("123.4").unwrap()
1732                ))
1733            )
1734        );
1735    }
1736
1737    #[test]
1738    fn decimal_with_exponent() {
1739        let src = "1.23456789123456e2";
1740        let num = parse_unwrap(src);
1741        assert_eq!(
1742            num,
1743            DatexExpression::Decimal(
1744                Decimal::from_string("123.456789123456").unwrap()
1745            )
1746        );
1747    }
1748
1749    #[test]
1750    fn decimal_with_negative_exponent() {
1751        let src = "1.23456789123456e-2";
1752        let num = parse_unwrap(src);
1753        assert_eq!(
1754            num,
1755            DatexExpression::Decimal(
1756                Decimal::from_string("0.0123456789123456").unwrap()
1757            )
1758        );
1759    }
1760
1761    #[test]
1762    fn decimal_with_positive_exponent() {
1763        let src = "1.23456789123456E+2";
1764        let num = parse_unwrap(src);
1765        assert_eq!(
1766            num,
1767            DatexExpression::Decimal(
1768                Decimal::from_string("123.456789123456").unwrap()
1769            )
1770        );
1771    }
1772
1773    #[test]
1774    fn decimal_with_trailing_point() {
1775        let src = "123.";
1776        let num = parse_unwrap(src);
1777        assert_eq!(
1778            num,
1779            DatexExpression::Decimal(Decimal::from_string("123.0").unwrap())
1780        );
1781    }
1782
1783    #[test]
1784    fn decimal_with_leading_point() {
1785        let src = ".456789123456";
1786        let num = parse_unwrap(src);
1787        assert_eq!(
1788            num,
1789            DatexExpression::Decimal(
1790                Decimal::from_string("0.456789123456").unwrap()
1791            )
1792        );
1793
1794        let src = ".423e-2";
1795        let num = parse_unwrap(src);
1796        assert_eq!(
1797            num,
1798            DatexExpression::Decimal(Decimal::from_string("0.00423").unwrap())
1799        );
1800    }
1801
1802    #[test]
1803    fn text_double_quotes() {
1804        let src = r#""Hello, world!""#;
1805        let text = parse_unwrap(src);
1806        assert_eq!(text, DatexExpression::Text("Hello, world!".to_string()));
1807    }
1808
1809    #[test]
1810    fn text_single_quotes() {
1811        let src = r#"'Hello, world!'"#;
1812        let text = parse_unwrap(src);
1813        assert_eq!(text, DatexExpression::Text("Hello, world!".to_string()));
1814    }
1815
1816    #[test]
1817    fn text_escape_sequences() {
1818        let src =
1819            r#""Hello, \"world\"! \n New line \t tab \uD83D\uDE00 \u2764""#;
1820        let text = parse_unwrap(src);
1821
1822        assert_eq!(
1823            text,
1824            DatexExpression::Text(
1825                "Hello, \"world\"! \n New line \t tab 😀 ❤".to_string()
1826            )
1827        );
1828    }
1829
1830    #[test]
1831    fn text_escape_sequences_2() {
1832        let src =
1833            r#""\u0048\u0065\u006C\u006C\u006F, \u2764\uFE0F, \uD83D\uDE00""#;
1834        let text = parse_unwrap(src);
1835        assert_eq!(text, DatexExpression::Text("Hello, ❤️, 😀".to_string()));
1836    }
1837
1838    #[test]
1839    fn text_nested_escape_sequences() {
1840        let src = r#""\\\\""#;
1841        let text = parse_unwrap(src);
1842        assert_eq!(text, DatexExpression::Text("\\\\".to_string()));
1843    }
1844
1845    #[test]
1846    fn text_nested_escape_sequences_2() {
1847        let src = r#""\\\"""#;
1848        let text = parse_unwrap(src);
1849        assert_eq!(text, DatexExpression::Text("\\\"".to_string()));
1850    }
1851
1852    #[test]
1853    fn empty_list() {
1854        let src = "[]";
1855        let arr = parse_unwrap(src);
1856        assert_eq!(arr, DatexExpression::List(vec![]));
1857    }
1858
1859    #[test]
1860    fn list_with_values() {
1861        let src = "[1, 2, 3, 4.5, \"text\"]";
1862        let arr = parse_unwrap(src);
1863
1864        assert_eq!(
1865            arr,
1866            DatexExpression::List(vec![
1867                DatexExpression::Integer(Integer::from(1)),
1868                DatexExpression::Integer(Integer::from(2)),
1869                DatexExpression::Integer(Integer::from(3)),
1870                DatexExpression::Decimal(Decimal::from_string("4.5").unwrap()),
1871                DatexExpression::Text("text".to_string()),
1872            ])
1873        );
1874    }
1875
1876    #[test]
1877    fn empty_map() {
1878        let src = "{}";
1879        let obj = parse_unwrap(src);
1880
1881        assert_eq!(obj, DatexExpression::Map(vec![]));
1882    }
1883
1884    #[test]
1885    fn list_of_lists() {
1886        let src = "[[1,2],3,[4]]";
1887        let arr = parse_unwrap(src);
1888
1889        assert_eq!(
1890            arr,
1891            DatexExpression::List(vec![
1892                DatexExpression::List(vec![
1893                    DatexExpression::Integer(Integer::from(1)),
1894                    DatexExpression::Integer(Integer::from(2)),
1895                ]),
1896                DatexExpression::Integer(Integer::from(3)),
1897                DatexExpression::List(vec![DatexExpression::Integer(
1898                    Integer::from(4)
1899                )]),
1900            ])
1901        );
1902    }
1903
1904    #[test]
1905    fn single_entry_map() {
1906        let src = "{x: 1}";
1907        let map = parse_unwrap(src);
1908        assert_eq!(
1909            map,
1910            DatexExpression::Map(vec![(
1911                DatexExpression::Text("x".to_string()),
1912                DatexExpression::Integer(Integer::from(1))
1913            )])
1914        );
1915    }
1916
1917    #[test]
1918    fn scoped_atom() {
1919        let src = "(1)";
1920        let atom = parse_unwrap(src);
1921        assert_eq!(atom, DatexExpression::Integer(Integer::from(1)));
1922    }
1923
1924    #[test]
1925    fn scoped_list() {
1926        let src = "(([1, 2, 3]))";
1927        let arr = parse_unwrap(src);
1928
1929        assert_eq!(
1930            arr,
1931            DatexExpression::List(vec![
1932                DatexExpression::Integer(Integer::from(1)),
1933                DatexExpression::Integer(Integer::from(2)),
1934                DatexExpression::Integer(Integer::from(3)),
1935            ])
1936        );
1937    }
1938
1939    #[test]
1940    fn map_with_key_value_pairs() {
1941        let src = r#"{"key1": "value1", "key2": 42, "key3": true}"#;
1942        let obj = parse_unwrap(src);
1943
1944        assert_eq!(
1945            obj,
1946            DatexExpression::Map(vec![
1947                (
1948                    DatexExpression::Text("key1".to_string()),
1949                    DatexExpression::Text("value1".to_string())
1950                ),
1951                (
1952                    DatexExpression::Text("key2".to_string()),
1953                    DatexExpression::Integer(Integer::from(42))
1954                ),
1955                (
1956                    DatexExpression::Text("key3".to_string()),
1957                    DatexExpression::Boolean(true)
1958                ),
1959            ])
1960        );
1961    }
1962
1963    #[test]
1964    fn dynamic_map_keys() {
1965        let src = r#"{(1): "value1", (2): 42, (3): true}"#;
1966        let obj = parse_unwrap(src);
1967        assert_eq!(
1968            obj,
1969            DatexExpression::Map(vec![
1970                (
1971                    DatexExpression::Integer(Integer::from(1)),
1972                    DatexExpression::Text("value1".to_string())
1973                ),
1974                (
1975                    DatexExpression::Integer(Integer::from(2)),
1976                    DatexExpression::Integer(Integer::from(42))
1977                ),
1978                (
1979                    DatexExpression::Integer(Integer::from(3)),
1980                    DatexExpression::Boolean(true)
1981                ),
1982            ])
1983        );
1984    }
1985
1986    #[test]
1987    fn add() {
1988        // Test with escaped characters in text
1989        let src = "1 + 2";
1990        let expr = parse_unwrap(src);
1991        assert_eq!(
1992            expr,
1993            DatexExpression::BinaryOperation(
1994                BinaryOperator::Arithmetic(ArithmeticOperator::Add),
1995                Box::new(DatexExpression::Integer(Integer::from(1))),
1996                Box::new(DatexExpression::Integer(Integer::from(2))),
1997                None
1998            )
1999        );
2000    }
2001
2002    #[test]
2003    fn add_complex_values() {
2004        // Test with escaped characters in text
2005        let src = "[] + x + (1 + 2)";
2006        let expr = parse_unwrap(src);
2007        assert_eq!(
2008            expr,
2009            DatexExpression::BinaryOperation(
2010                BinaryOperator::Arithmetic(ArithmeticOperator::Add),
2011                Box::new(DatexExpression::BinaryOperation(
2012                    BinaryOperator::Arithmetic(ArithmeticOperator::Add),
2013                    Box::new(DatexExpression::List(vec![])),
2014                    Box::new(DatexExpression::Identifier("x".to_string())),
2015                    None
2016                )),
2017                Box::new(DatexExpression::BinaryOperation(
2018                    BinaryOperator::Arithmetic(ArithmeticOperator::Add),
2019                    Box::new(DatexExpression::Integer(Integer::from(1))),
2020                    Box::new(DatexExpression::Integer(Integer::from(2))),
2021                    None
2022                )),
2023                None
2024            )
2025        );
2026    }
2027
2028    #[test]
2029    fn subtract() {
2030        let src = "5 - 3";
2031        let expr = parse_unwrap(src);
2032        assert_eq!(
2033            expr,
2034            DatexExpression::BinaryOperation(
2035                BinaryOperator::Arithmetic(ArithmeticOperator::Subtract),
2036                Box::new(DatexExpression::Integer(Integer::from(5))),
2037                Box::new(DatexExpression::Integer(Integer::from(3))),
2038                None
2039            )
2040        );
2041
2042        let src = "5-3";
2043        let expr = parse_unwrap(src);
2044        assert_eq!(
2045            expr,
2046            DatexExpression::BinaryOperation(
2047                BinaryOperator::Arithmetic(ArithmeticOperator::Subtract),
2048                Box::new(DatexExpression::Integer(Integer::from(5))),
2049                Box::new(DatexExpression::Integer(Integer::from(3))),
2050                None
2051            )
2052        );
2053
2054        let src = "5- 3";
2055        let expr = parse_unwrap(src);
2056        assert_eq!(
2057            expr,
2058            DatexExpression::BinaryOperation(
2059                BinaryOperator::Arithmetic(ArithmeticOperator::Subtract),
2060                Box::new(DatexExpression::Integer(Integer::from(5))),
2061                Box::new(DatexExpression::Integer(Integer::from(3))),
2062                None
2063            )
2064        );
2065
2066        let src = "5 -3";
2067        let expr = parse_unwrap(src);
2068        assert_eq!(
2069            expr,
2070            DatexExpression::BinaryOperation(
2071                BinaryOperator::Arithmetic(ArithmeticOperator::Subtract),
2072                Box::new(DatexExpression::Integer(Integer::from(5))),
2073                Box::new(DatexExpression::Integer(Integer::from(3))),
2074                None
2075            )
2076        );
2077    }
2078
2079    #[test]
2080    fn multiply() {
2081        let src = "4 * 2";
2082        let expr = parse_unwrap(src);
2083        assert_eq!(
2084            expr,
2085            DatexExpression::BinaryOperation(
2086                BinaryOperator::Arithmetic(ArithmeticOperator::Multiply),
2087                Box::new(DatexExpression::Integer(Integer::from(4))),
2088                Box::new(DatexExpression::Integer(Integer::from(2))),
2089                None
2090            )
2091        );
2092    }
2093
2094    #[test]
2095    fn divide() {
2096        let src = "8 / 2";
2097        let expr = parse_unwrap(src);
2098        assert_eq!(
2099            expr,
2100            DatexExpression::BinaryOperation(
2101                BinaryOperator::Arithmetic(ArithmeticOperator::Divide),
2102                Box::new(DatexExpression::Integer(Integer::from(8))),
2103                Box::new(DatexExpression::Integer(Integer::from(2))),
2104                None
2105            )
2106        );
2107
2108        let src = "8 /2";
2109        let expr = parse_unwrap(src);
2110        assert_eq!(
2111            expr,
2112            DatexExpression::BinaryOperation(
2113                BinaryOperator::Arithmetic(ArithmeticOperator::Divide),
2114                Box::new(DatexExpression::Integer(Integer::from(8))),
2115                Box::new(DatexExpression::Integer(Integer::from(2))),
2116                None
2117            )
2118        );
2119
2120        let src = "8u8/2";
2121        let expr = parse_unwrap(src);
2122        assert_eq!(
2123            expr,
2124            DatexExpression::BinaryOperation(
2125                BinaryOperator::Arithmetic(ArithmeticOperator::Divide),
2126                Box::new(DatexExpression::TypedInteger(TypedInteger::from(
2127                    8u8
2128                ))),
2129                Box::new(DatexExpression::Integer(Integer::from(2))),
2130                None
2131            )
2132        );
2133    }
2134
2135    #[test]
2136    fn complex_calculation() {
2137        let src = "1 + 2 * 3 + 4";
2138        let expr = parse_unwrap(src);
2139        assert_eq!(
2140            expr,
2141            DatexExpression::BinaryOperation(
2142                BinaryOperator::Arithmetic(ArithmeticOperator::Add),
2143                Box::new(DatexExpression::BinaryOperation(
2144                    BinaryOperator::Arithmetic(ArithmeticOperator::Add),
2145                    Box::new(DatexExpression::Integer(Integer::from(1))),
2146                    Box::new(DatexExpression::BinaryOperation(
2147                        BinaryOperator::Arithmetic(
2148                            ArithmeticOperator::Multiply
2149                        ),
2150                        Box::new(DatexExpression::Integer(Integer::from(2))),
2151                        Box::new(DatexExpression::Integer(Integer::from(3))),
2152                        None
2153                    )),
2154                    None
2155                )),
2156                Box::new(DatexExpression::Integer(Integer::from(4))),
2157                None
2158            )
2159        );
2160    }
2161
2162    #[test]
2163    fn nested_addition() {
2164        let src = "1 + (2 + 3)";
2165        let expr = parse_unwrap(src);
2166        assert_eq!(
2167            expr,
2168            DatexExpression::BinaryOperation(
2169                BinaryOperator::Arithmetic(ArithmeticOperator::Add),
2170                Box::new(DatexExpression::Integer(Integer::from(1))),
2171                Box::new(DatexExpression::BinaryOperation(
2172                    BinaryOperator::Arithmetic(ArithmeticOperator::Add),
2173                    Box::new(DatexExpression::Integer(Integer::from(2))),
2174                    Box::new(DatexExpression::Integer(Integer::from(3))),
2175                    None
2176                )),
2177                None
2178            )
2179        );
2180    }
2181
2182    #[test]
2183    fn add_statements_1() {
2184        // Test with escaped characters in text
2185        let src = "1 + (2;3)";
2186        let expr = parse_unwrap(src);
2187        assert_eq!(
2188            expr,
2189            DatexExpression::BinaryOperation(
2190                BinaryOperator::Arithmetic(ArithmeticOperator::Add),
2191                Box::new(DatexExpression::Integer(Integer::from(1))),
2192                Box::new(DatexExpression::Statements(vec![
2193                    Statement {
2194                        expression: DatexExpression::Integer(Integer::from(2)),
2195                        is_terminated: true,
2196                    },
2197                    Statement {
2198                        expression: DatexExpression::Integer(Integer::from(3)),
2199                        is_terminated: false,
2200                    },
2201                ])),
2202                None
2203            )
2204        );
2205    }
2206
2207    #[test]
2208    fn add_statements_2() {
2209        // Test with escaped characters in text
2210        let src = "(1;2) + 3";
2211        let expr = parse_unwrap(src);
2212        assert_eq!(
2213            expr,
2214            DatexExpression::BinaryOperation(
2215                BinaryOperator::Arithmetic(ArithmeticOperator::Add),
2216                Box::new(DatexExpression::Statements(vec![
2217                    Statement {
2218                        expression: DatexExpression::Integer(Integer::from(1)),
2219                        is_terminated: true,
2220                    },
2221                    Statement {
2222                        expression: DatexExpression::Integer(Integer::from(2)),
2223                        is_terminated: false,
2224                    },
2225                ])),
2226                Box::new(DatexExpression::Integer(Integer::from(3))),
2227                None
2228            )
2229        );
2230    }
2231
2232    #[test]
2233    fn nested_expressions() {
2234        let src = "[1 + 2]";
2235        let expr = parse_unwrap(src);
2236        assert_eq!(
2237            expr,
2238            DatexExpression::List(vec![DatexExpression::BinaryOperation(
2239                BinaryOperator::Arithmetic(ArithmeticOperator::Add),
2240                Box::new(DatexExpression::Integer(Integer::from(1))),
2241                Box::new(DatexExpression::Integer(Integer::from(2))),
2242                None
2243            )])
2244        );
2245    }
2246
2247    #[test]
2248    fn multi_statement_expression() {
2249        let src = "1;2";
2250        let expr = parse_unwrap(src);
2251        assert_eq!(
2252            expr,
2253            DatexExpression::Statements(vec![
2254                Statement {
2255                    expression: DatexExpression::Integer(Integer::from(1)),
2256                    is_terminated: true,
2257                },
2258                Statement {
2259                    expression: DatexExpression::Integer(Integer::from(2)),
2260                    is_terminated: false,
2261                },
2262            ])
2263        );
2264    }
2265
2266    #[test]
2267    fn nested_scope_statements() {
2268        let src = "(1; 2; 3)";
2269        let expr = parse_unwrap(src);
2270        assert_eq!(
2271            expr,
2272            DatexExpression::Statements(vec![
2273                Statement {
2274                    expression: DatexExpression::Integer(Integer::from(1)),
2275                    is_terminated: true,
2276                },
2277                Statement {
2278                    expression: DatexExpression::Integer(Integer::from(2)),
2279                    is_terminated: true,
2280                },
2281                Statement {
2282                    expression: DatexExpression::Integer(Integer::from(3)),
2283                    is_terminated: false,
2284                },
2285            ])
2286        );
2287    }
2288    #[test]
2289    fn nested_scope_statements_closed() {
2290        let src = "(1; 2; 3;)";
2291        let expr = parse_unwrap(src);
2292        assert_eq!(
2293            expr,
2294            DatexExpression::Statements(vec![
2295                Statement {
2296                    expression: DatexExpression::Integer(Integer::from(1)),
2297                    is_terminated: true,
2298                },
2299                Statement {
2300                    expression: DatexExpression::Integer(Integer::from(2)),
2301                    is_terminated: true,
2302                },
2303                Statement {
2304                    expression: DatexExpression::Integer(Integer::from(3)),
2305                    is_terminated: true,
2306                },
2307            ])
2308        );
2309    }
2310
2311    #[test]
2312    fn nested_statements_in_map() {
2313        let src = r#"{"key": (1; 2; 3)}"#;
2314        let expr = parse_unwrap(src);
2315        assert_eq!(
2316            expr,
2317            DatexExpression::Map(vec![(
2318                DatexExpression::Text("key".to_string()),
2319                DatexExpression::Statements(vec![
2320                    Statement {
2321                        expression: DatexExpression::Integer(Integer::from(1)),
2322                        is_terminated: true,
2323                    },
2324                    Statement {
2325                        expression: DatexExpression::Integer(Integer::from(2)),
2326                        is_terminated: true,
2327                    },
2328                    Statement {
2329                        expression: DatexExpression::Integer(Integer::from(3)),
2330                        is_terminated: false,
2331                    },
2332                ])
2333            ),])
2334        );
2335    }
2336
2337    #[test]
2338    fn single_statement() {
2339        let src = "1;";
2340        let expr = parse_unwrap(src);
2341        assert_eq!(
2342            expr,
2343            DatexExpression::Statements(vec![Statement {
2344                expression: DatexExpression::Integer(Integer::from(1)),
2345                is_terminated: true,
2346            },])
2347        );
2348    }
2349
2350    #[test]
2351    fn empty_statement() {
2352        let src = ";";
2353        let expr = parse_unwrap(src);
2354        assert_eq!(expr, DatexExpression::Statements(vec![]));
2355    }
2356
2357    #[test]
2358    fn empty_statement_multiple() {
2359        let src = ";;;";
2360        let expr = parse_unwrap(src);
2361        assert_eq!(expr, DatexExpression::Statements(vec![]));
2362    }
2363
2364    #[test]
2365    fn variable_expression() {
2366        let src = "myVar";
2367        let expr = parse_unwrap(src);
2368        assert_eq!(expr, DatexExpression::Identifier("myVar".to_string()));
2369    }
2370
2371    #[test]
2372    fn variable_expression_with_operations() {
2373        let src = "myVar + 1";
2374        let expr = parse_unwrap(src);
2375        assert_eq!(
2376            expr,
2377            DatexExpression::BinaryOperation(
2378                BinaryOperator::Arithmetic(ArithmeticOperator::Add),
2379                Box::new(DatexExpression::Identifier("myVar".to_string())),
2380                Box::new(DatexExpression::Integer(Integer::from(1))),
2381                None
2382            )
2383        );
2384    }
2385
2386    #[test]
2387    fn apply_expression() {
2388        let src = "myFunc(1, 2, 3)";
2389        let expr = parse_unwrap(src);
2390        assert_eq!(
2391            expr,
2392            DatexExpression::ApplyChain(
2393                Box::new(DatexExpression::Identifier("myFunc".to_string())),
2394                vec![ApplyOperation::FunctionCall(DatexExpression::List(
2395                    vec![
2396                        DatexExpression::Integer(Integer::from(1)),
2397                        DatexExpression::Integer(Integer::from(2)),
2398                        DatexExpression::Integer(Integer::from(3)),
2399                    ]
2400                ),)],
2401            )
2402        );
2403    }
2404
2405    #[test]
2406    fn apply_empty() {
2407        let src = "myFunc()";
2408        let expr = parse_unwrap(src);
2409        assert_eq!(
2410            expr,
2411            DatexExpression::ApplyChain(
2412                Box::new(DatexExpression::Identifier("myFunc".to_string())),
2413                vec![ApplyOperation::FunctionCall(DatexExpression::Map(
2414                    vec![]
2415                ))],
2416            )
2417        );
2418    }
2419
2420    #[test]
2421    fn apply_multiple() {
2422        let src = "myFunc(1)(2, 3)";
2423        let expr = parse_unwrap(src);
2424        assert_eq!(
2425            expr,
2426            DatexExpression::ApplyChain(
2427                Box::new(DatexExpression::Identifier("myFunc".to_string())),
2428                vec![
2429                    ApplyOperation::FunctionCall(DatexExpression::List(vec![
2430                        DatexExpression::Integer(Integer::from(1))
2431                    ])),
2432                    ApplyOperation::FunctionCall(DatexExpression::List(vec![
2433                        DatexExpression::Integer(Integer::from(2)),
2434                        DatexExpression::Integer(Integer::from(3)),
2435                    ]))
2436                ],
2437            )
2438        );
2439    }
2440
2441    #[test]
2442    fn apply_atom() {
2443        let src = "print 'test'";
2444        let expr = parse_unwrap(src);
2445        assert_eq!(
2446            expr,
2447            DatexExpression::ApplyChain(
2448                Box::new(DatexExpression::Identifier("print".to_string())),
2449                vec![ApplyOperation::FunctionCall(DatexExpression::Text(
2450                    "test".to_string()
2451                ))],
2452            )
2453        );
2454    }
2455
2456    #[test]
2457    fn property_access() {
2458        let src = "myObj.myProp";
2459        let expr = parse_unwrap(src);
2460        assert_eq!(
2461            expr,
2462            DatexExpression::ApplyChain(
2463                Box::new(DatexExpression::Identifier("myObj".to_string())),
2464                vec![ApplyOperation::PropertyAccess(DatexExpression::Text(
2465                    "myProp".to_string()
2466                ))],
2467            )
2468        );
2469    }
2470
2471    #[test]
2472    fn property_access_scoped() {
2473        let src = "myObj.(1)";
2474        let expr = parse_unwrap(src);
2475        assert_eq!(
2476            expr,
2477            DatexExpression::ApplyChain(
2478                Box::new(DatexExpression::Identifier("myObj".to_string())),
2479                vec![ApplyOperation::PropertyAccess(DatexExpression::Integer(
2480                    Integer::from(1)
2481                ))],
2482            )
2483        );
2484    }
2485
2486    #[test]
2487    fn property_access_multiple() {
2488        let src = "myObj.myProp.anotherProp.(1 + 2).(x;y)";
2489        let expr = parse_unwrap(src);
2490        assert_eq!(
2491            expr,
2492            DatexExpression::ApplyChain(
2493                Box::new(DatexExpression::Identifier("myObj".to_string())),
2494                vec![
2495                    ApplyOperation::PropertyAccess(DatexExpression::Text(
2496                        "myProp".to_string()
2497                    )),
2498                    ApplyOperation::PropertyAccess(DatexExpression::Text(
2499                        "anotherProp".to_string()
2500                    )),
2501                    ApplyOperation::PropertyAccess(
2502                        DatexExpression::BinaryOperation(
2503                            BinaryOperator::Arithmetic(ArithmeticOperator::Add),
2504                            Box::new(DatexExpression::Integer(Integer::from(
2505                                1
2506                            ))),
2507                            Box::new(DatexExpression::Integer(Integer::from(
2508                                2
2509                            ))),
2510                            None
2511                        )
2512                    ),
2513                    ApplyOperation::PropertyAccess(
2514                        DatexExpression::Statements(vec![
2515                            Statement {
2516                                expression: DatexExpression::Identifier(
2517                                    "x".to_string()
2518                                ),
2519                                is_terminated: true,
2520                            },
2521                            Statement {
2522                                expression: DatexExpression::Identifier(
2523                                    "y".to_string()
2524                                ),
2525                                is_terminated: false,
2526                            },
2527                        ])
2528                    ),
2529                ],
2530            )
2531        );
2532    }
2533
2534    #[test]
2535    fn property_access_and_apply() {
2536        let src = "myObj.myProp(1, 2)";
2537        let expr = parse_unwrap(src);
2538        assert_eq!(
2539            expr,
2540            DatexExpression::ApplyChain(
2541                Box::new(DatexExpression::Identifier("myObj".to_string())),
2542                vec![
2543                    ApplyOperation::PropertyAccess(DatexExpression::Text(
2544                        "myProp".to_string()
2545                    )),
2546                    ApplyOperation::FunctionCall(DatexExpression::List(vec![
2547                        DatexExpression::Integer(Integer::from(1)),
2548                        DatexExpression::Integer(Integer::from(2)),
2549                    ])),
2550                ],
2551            )
2552        );
2553    }
2554
2555    #[test]
2556    fn apply_and_property_access() {
2557        let src = "myFunc(1).myProp";
2558        let expr = parse_unwrap(src);
2559        assert_eq!(
2560            expr,
2561            DatexExpression::ApplyChain(
2562                Box::new(DatexExpression::Identifier("myFunc".to_string())),
2563                vec![
2564                    ApplyOperation::FunctionCall(DatexExpression::List(vec![
2565                        DatexExpression::Integer(Integer::from(1)),
2566                    ])),
2567                    ApplyOperation::PropertyAccess(DatexExpression::Text(
2568                        "myProp".to_string()
2569                    )),
2570                ],
2571            )
2572        );
2573    }
2574
2575    #[test]
2576    fn nested_apply_and_property_access() {
2577        let src = "((x(1)).y).z";
2578        let expr = parse_unwrap(src);
2579        assert_eq!(
2580            expr,
2581            DatexExpression::ApplyChain(
2582                Box::new(DatexExpression::ApplyChain(
2583                    Box::new(DatexExpression::ApplyChain(
2584                        Box::new(DatexExpression::Identifier("x".to_string())),
2585                        vec![ApplyOperation::FunctionCall(
2586                            DatexExpression::List(vec![
2587                                DatexExpression::Integer(Integer::from(1))
2588                            ])
2589                        )],
2590                    )),
2591                    vec![ApplyOperation::PropertyAccess(
2592                        DatexExpression::Text("y".to_string())
2593                    )],
2594                )),
2595                vec![ApplyOperation::PropertyAccess(DatexExpression::Text(
2596                    "z".to_string()
2597                ))],
2598            )
2599        );
2600    }
2601
2602    #[test]
2603    fn type_declaration_statement() {
2604        let src = "type User = { age: 42, name: \"John\" };";
2605        let expr = parse_unwrap(src);
2606        assert_eq!(
2607            expr,
2608            DatexExpression::Statements(vec![Statement {
2609                expression: DatexExpression::TypeDeclaration {
2610                    id: None,
2611                    name: "User".to_string(),
2612                    value: TypeExpression::StructuralMap(vec![
2613                        (
2614                            TypeExpression::Text("age".to_string()),
2615                            TypeExpression::Integer(Integer::from(42))
2616                        ),
2617                        (
2618                            TypeExpression::Text("name".to_string()),
2619                            TypeExpression::Text("John".to_string())
2620                        ),
2621                    ]),
2622                    hoisted: false,
2623                },
2624                is_terminated: true,
2625            },])
2626        );
2627
2628        // make sure { type: 42, name: "John" } is not parsed as type declaration
2629        let src = r#"{ type: 42, name: "John" };"#;
2630        let expr = parse_unwrap(src);
2631        assert_eq!(
2632            expr,
2633            DatexExpression::Statements(vec![Statement {
2634                expression: DatexExpression::Map(vec![
2635                    (
2636                        DatexExpression::Text("type".to_string()),
2637                        DatexExpression::Integer(Integer::from(42))
2638                    ),
2639                    (
2640                        DatexExpression::Text("name".to_string()),
2641                        DatexExpression::Text("John".to_string())
2642                    ),
2643                ]),
2644                is_terminated: true,
2645            },])
2646        );
2647    }
2648
2649    #[test]
2650    fn variable_declaration_statement() {
2651        let src = "const x = 42;";
2652        let expr = parse_unwrap(src);
2653        assert_eq!(
2654            expr,
2655            DatexExpression::Statements(vec![Statement {
2656                expression: DatexExpression::VariableDeclaration {
2657                    id: None,
2658                    kind: VariableKind::Const,
2659                    type_annotation: None,
2660                    name: "x".to_string(),
2661                    init_expression: Box::new(DatexExpression::Integer(
2662                        Integer::from(42)
2663                    )),
2664                },
2665                is_terminated: true,
2666            },])
2667        );
2668    }
2669
2670    #[test]
2671    fn variable_declaration_with_expression() {
2672        let src = "var x = 1 + 2";
2673        let expr = parse_unwrap(src);
2674        assert_eq!(
2675            expr,
2676            DatexExpression::VariableDeclaration {
2677                id: None,
2678                kind: VariableKind::Var,
2679                type_annotation: None,
2680                name: "x".to_string(),
2681                init_expression: Box::new(DatexExpression::BinaryOperation(
2682                    BinaryOperator::Arithmetic(ArithmeticOperator::Add),
2683                    Box::new(DatexExpression::Integer(Integer::from(1))),
2684                    Box::new(DatexExpression::Integer(Integer::from(2))),
2685                    None
2686                ))
2687            }
2688        );
2689    }
2690
2691    #[test]
2692    fn variable_assignment() {
2693        let src = "x = 42";
2694        let expr = parse_unwrap(src);
2695        assert_eq!(
2696            expr,
2697            DatexExpression::VariableAssignment(
2698                AssignmentOperator::Assign,
2699                None,
2700                "x".to_string(),
2701                Box::new(DatexExpression::Integer(Integer::from(42))),
2702            )
2703        );
2704    }
2705
2706    #[test]
2707    fn variable_assignment_expression() {
2708        let src = "x = (y = 1)";
2709        let expr = parse_unwrap(src);
2710        assert_eq!(
2711            expr,
2712            DatexExpression::VariableAssignment(
2713                AssignmentOperator::Assign,
2714                None,
2715                "x".to_string(),
2716                Box::new(DatexExpression::VariableAssignment(
2717                    AssignmentOperator::Assign,
2718                    None,
2719                    "y".to_string(),
2720                    Box::new(DatexExpression::Integer(Integer::from(1))),
2721                )),
2722            )
2723        );
2724    }
2725
2726    #[test]
2727    fn variable_assignment_expression_in_list() {
2728        let src = "[x = 1]";
2729        let expr = parse_unwrap(src);
2730        assert_eq!(
2731            expr,
2732            DatexExpression::List(vec![DatexExpression::VariableAssignment(
2733                AssignmentOperator::Assign,
2734                None,
2735                "x".to_string(),
2736                Box::new(DatexExpression::Integer(Integer::from(1))),
2737            )])
2738        );
2739    }
2740
2741    #[test]
2742    fn apply_in_list() {
2743        let src = "[myFunc(1)]";
2744        let expr = parse_unwrap(src);
2745        assert_eq!(
2746            expr,
2747            DatexExpression::List(vec![DatexExpression::ApplyChain(
2748                Box::new(DatexExpression::Identifier("myFunc".to_string())),
2749                vec![ApplyOperation::FunctionCall(DatexExpression::List(
2750                    vec![DatexExpression::Integer(Integer::from(1))]
2751                ))]
2752            ),])
2753        );
2754    }
2755
2756    #[test]
2757    fn variant_accessor() {
2758        let res = parse_unwrap("integer/u8");
2759        assert_eq!(
2760            res,
2761            DatexExpression::BinaryOperation(
2762                BinaryOperator::VariantAccess,
2763                Box::new(DatexExpression::Identifier("integer".to_string())),
2764                Box::new(DatexExpression::Identifier("u8".to_string())),
2765                None
2766            )
2767        );
2768
2769        let res = parse_unwrap("undeclared/u8");
2770        assert_eq!(
2771            res,
2772            DatexExpression::BinaryOperation(
2773                BinaryOperator::VariantAccess,
2774                Box::new(DatexExpression::Identifier("undeclared".to_string())),
2775                Box::new(DatexExpression::Identifier("u8".to_string())),
2776                None
2777            )
2778        );
2779    }
2780
2781    #[test]
2782    fn fraction() {
2783        // fraction
2784        let res = parse_unwrap("42/3");
2785        assert_eq!(
2786            res,
2787            DatexExpression::Decimal(Decimal::from_string("42/3").unwrap())
2788        );
2789
2790        let src = "1/3";
2791        let val = try_parse_to_value_container(src);
2792        assert_eq!(
2793            val,
2794            ValueContainer::from(Decimal::from_string("1/3").unwrap())
2795        );
2796
2797        // divison
2798        let res = parse_unwrap("42.4/3");
2799        assert_eq!(
2800            res,
2801            DatexExpression::BinaryOperation(
2802                BinaryOperator::Arithmetic(ArithmeticOperator::Divide),
2803                Box::new(DatexExpression::Decimal(
2804                    Decimal::from_string("42.4").unwrap()
2805                )),
2806                Box::new(DatexExpression::Integer(Integer::from(3))),
2807                None
2808            )
2809        );
2810
2811        let res = parse_unwrap("42 /3");
2812        assert_eq!(
2813            res,
2814            DatexExpression::BinaryOperation(
2815                BinaryOperator::Arithmetic(ArithmeticOperator::Divide),
2816                Box::new(DatexExpression::Integer(Integer::from(42))),
2817                Box::new(DatexExpression::Integer(Integer::from(3))),
2818                None
2819            )
2820        );
2821
2822        let res = parse_unwrap("42/ 3");
2823        assert_eq!(
2824            res,
2825            DatexExpression::BinaryOperation(
2826                BinaryOperator::Arithmetic(ArithmeticOperator::Divide),
2827                Box::new(DatexExpression::Integer(Integer::from(42))),
2828                Box::new(DatexExpression::Integer(Integer::from(3))),
2829                None
2830            )
2831        );
2832    }
2833
2834    #[test]
2835    fn endpoint() {
2836        let src = "@jonas";
2837        let val = try_parse_to_value_container(src);
2838        assert_eq!(
2839            val,
2840            ValueContainer::from(Endpoint::from_str("@jonas").unwrap())
2841        );
2842    }
2843
2844    // TODO #159:
2845    // #[test]
2846    // fn variable_assignment_multiple() {
2847    //     let src = "x = y = 42";
2848    //     let expr = parse_unwrap(src);
2849    //     assert_eq!(
2850    //         expr,
2851    //         DatexExpression::VariableAssignment(
2852    //             "x".to_string(),
2853    //             Box::new(DatexExpression::VariableAssignment(
2854    //                 "y".to_string(),
2855    //                 Box::new(DatexExpression::Integer(Integer::from(42))),
2856    //             )),
2857    //         )
2858    //     );
2859    // }
2860
2861    #[test]
2862    fn variable_declaration_and_assignment() {
2863        let src = "var x = 42; x = 100 * 10;";
2864        let expr = parse_unwrap(src);
2865        assert_eq!(
2866            expr,
2867            DatexExpression::Statements(vec![
2868                Statement {
2869                    expression: DatexExpression::VariableDeclaration {
2870                        id: None,
2871                        kind: VariableKind::Var,
2872                        name: "x".to_string(),
2873                        init_expression: Box::new(DatexExpression::Integer(
2874                            Integer::from(42)
2875                        )),
2876                        type_annotation: None
2877                    },
2878                    is_terminated: true,
2879                },
2880                Statement {
2881                    expression: DatexExpression::VariableAssignment(
2882                        AssignmentOperator::Assign,
2883                        None,
2884                        "x".to_string(),
2885                        Box::new(DatexExpression::BinaryOperation(
2886                            BinaryOperator::Arithmetic(
2887                                ArithmeticOperator::Multiply
2888                            ),
2889                            Box::new(DatexExpression::Integer(Integer::from(
2890                                100
2891                            ))),
2892                            Box::new(DatexExpression::Integer(Integer::from(
2893                                10
2894                            ))),
2895                            None
2896                        )),
2897                    ),
2898                    is_terminated: true,
2899                },
2900            ])
2901        );
2902    }
2903
2904    #[test]
2905    fn placeholder() {
2906        let src = "?";
2907        let expr = parse_unwrap(src);
2908        assert_eq!(expr, DatexExpression::Placeholder);
2909    }
2910
2911    #[test]
2912    fn integer_to_value_container() {
2913        let src = "123456789123456789";
2914        let val = try_parse_to_value_container(src);
2915        assert_eq!(
2916            val,
2917            ValueContainer::from(
2918                Integer::from_string("123456789123456789").unwrap()
2919            )
2920        );
2921    }
2922
2923    #[test]
2924    fn decimal_to_value_container() {
2925        let src = "123.456789123456";
2926        let val = try_parse_to_value_container(src);
2927        assert_eq!(
2928            val,
2929            ValueContainer::from(
2930                Decimal::from_string("123.456789123456").unwrap()
2931            )
2932        );
2933    }
2934
2935    #[test]
2936    fn text_to_value_container() {
2937        let src = r#""Hello, world!""#;
2938        let val = try_parse_to_value_container(src);
2939        assert_eq!(val, ValueContainer::from("Hello, world!".to_string()));
2940    }
2941
2942    #[test]
2943    fn list_to_value_container() {
2944        let src = "[1, 2, 3, 4.5, \"text\"]";
2945        let val = try_parse_to_value_container(src);
2946        let value_container_list: Vec<ValueContainer> = vec![
2947            Integer::from(1).into(),
2948            Integer::from(2).into(),
2949            Integer::from(3).into(),
2950            Decimal::from_string("4.5").unwrap().into(),
2951            "text".to_string().into(),
2952        ];
2953        assert_eq!(val, ValueContainer::from(value_container_list));
2954    }
2955
2956    #[test]
2957    fn json_to_value_container() {
2958        let src = r#"
2959            {
2960                "name": "Test",
2961                "value": 42,
2962                "active": true,
2963                "items": [1, 2, 3, 0.5],
2964                "nested": {
2965                    "key": "value"
2966                }
2967            }
2968        "#;
2969
2970        let val = try_parse_to_value_container(src);
2971        let value_container_list: Vec<ValueContainer> = vec![
2972            Integer::from(1).into(),
2973            Integer::from(2).into(),
2974            Integer::from(3).into(),
2975            Decimal::from_string("0.5").unwrap().into(),
2976        ];
2977        let value_container_inner_map: ValueContainer =
2978            ValueContainer::from(Map::from(
2979                vec![("key".to_string(), "value".to_string().into())]
2980                    .into_iter()
2981                    .collect::<HashMap<String, ValueContainer>>(),
2982            ));
2983        let value_container_map: ValueContainer =
2984            ValueContainer::from(Map::from(
2985                vec![
2986                    ("name".to_string(), "Test".to_string().into()),
2987                    ("value".to_string(), Integer::from(42).into()),
2988                    ("active".to_string(), true.into()),
2989                    ("items".to_string(), value_container_list.into()),
2990                    ("nested".to_string(), value_container_inner_map),
2991                ]
2992                .into_iter()
2993                .collect::<HashMap<String, ValueContainer>>(),
2994            ));
2995        assert_eq!(val, value_container_map);
2996    }
2997
2998    #[test]
2999    fn invalid_value_containers() {
3000        let src = "1 + 2";
3001        let expr = parse_unwrap(src);
3002        assert!(
3003            ValueContainer::try_from(&expr).is_err(),
3004            "Expected error when converting expression to ValueContainer"
3005        );
3006
3007        let src = "xy";
3008        let expr = parse_unwrap(src);
3009        assert!(
3010            ValueContainer::try_from(&expr).is_err(),
3011            "Expected error when converting expression to ValueContainer"
3012        );
3013
3014        let src = "x()";
3015        let expr = parse_unwrap(src);
3016        assert!(
3017            ValueContainer::try_from(&expr).is_err(),
3018            "Expected error when converting expression to ValueContainer"
3019        );
3020    }
3021
3022    #[test]
3023    fn decimal_nan() {
3024        let src = "NaN";
3025        let num = parse_unwrap(src);
3026        assert_matches!(num, DatexExpression::Decimal(Decimal::NaN));
3027
3028        let src = "nan";
3029        let num = parse_unwrap(src);
3030        assert_matches!(num, DatexExpression::Decimal(Decimal::NaN));
3031    }
3032
3033    #[test]
3034    fn decimal_infinity() {
3035        let src = "Infinity";
3036        let num = parse_unwrap(src);
3037        assert_eq!(num, DatexExpression::Decimal(Decimal::Infinity));
3038
3039        let src = "-Infinity";
3040        let num = parse_unwrap(src);
3041        assert_eq!(num, DatexExpression::Decimal(Decimal::NegInfinity));
3042
3043        let src = "infinity";
3044        let num = parse_unwrap(src);
3045        assert_eq!(num, DatexExpression::Decimal(Decimal::Infinity));
3046
3047        let src = "-infinity";
3048        let num = parse_unwrap(src);
3049        assert_eq!(num, DatexExpression::Decimal(Decimal::NegInfinity));
3050    }
3051
3052    #[test]
3053    fn comment() {
3054        let src = "// This is a comment\n1 + 2";
3055        let expr = parse_unwrap(src);
3056        assert_eq!(
3057            expr,
3058            DatexExpression::BinaryOperation(
3059                BinaryOperator::Arithmetic(ArithmeticOperator::Add),
3060                Box::new(DatexExpression::Integer(Integer::from(1))),
3061                Box::new(DatexExpression::Integer(Integer::from(2))),
3062                None
3063            )
3064        );
3065
3066        let src = "1 + //test\n2";
3067        let expr = parse_unwrap(src);
3068        assert_eq!(
3069            expr,
3070            DatexExpression::BinaryOperation(
3071                BinaryOperator::Arithmetic(ArithmeticOperator::Add),
3072                Box::new(DatexExpression::Integer(Integer::from(1))),
3073                Box::new(DatexExpression::Integer(Integer::from(2))),
3074                None
3075            )
3076        );
3077    }
3078
3079    #[test]
3080    fn multiline_comment() {
3081        let src = "/* This is a\nmultiline comment */\n1 + 2";
3082        let expr = parse_unwrap(src);
3083        assert_eq!(
3084            expr,
3085            DatexExpression::BinaryOperation(
3086                BinaryOperator::Arithmetic(ArithmeticOperator::Add),
3087                Box::new(DatexExpression::Integer(Integer::from(1))),
3088                Box::new(DatexExpression::Integer(Integer::from(2))),
3089                None
3090            )
3091        );
3092
3093        let src = "1 + /*test*/ 2";
3094        let expr = parse_unwrap(src);
3095        assert_eq!(
3096            expr,
3097            DatexExpression::BinaryOperation(
3098                BinaryOperator::Arithmetic(ArithmeticOperator::Add),
3099                Box::new(DatexExpression::Integer(Integer::from(1))),
3100                Box::new(DatexExpression::Integer(Integer::from(2))),
3101                None
3102            )
3103        );
3104    }
3105
3106    #[test]
3107    fn shebang() {
3108        let src = "#!/usr/bin/env datex\n1 + 2";
3109        let expr = parse_unwrap(src);
3110        assert_eq!(
3111            expr,
3112            DatexExpression::BinaryOperation(
3113                BinaryOperator::Arithmetic(ArithmeticOperator::Add),
3114                Box::new(DatexExpression::Integer(Integer::from(1))),
3115                Box::new(DatexExpression::Integer(Integer::from(2))),
3116                None
3117            )
3118        );
3119
3120        let src = "1;\n#!/usr/bin/env datex\n2";
3121        // syntax error
3122        let res = parse(src);
3123        assert!(
3124            res.is_err(),
3125            "Expected error when parsing expression with shebang"
3126        );
3127    }
3128
3129    #[test]
3130    fn remote_execution() {
3131        let src = "a :: b";
3132        let expr = parse_unwrap(src);
3133        assert_eq!(
3134            expr,
3135            DatexExpression::RemoteExecution(
3136                Box::new(DatexExpression::Identifier("a".to_string())),
3137                Box::new(DatexExpression::Identifier("b".to_string()))
3138            )
3139        );
3140    }
3141    #[test]
3142    fn remote_execution_no_space() {
3143        let src = "a::b";
3144        let expr = parse_unwrap(src);
3145        assert_eq!(
3146            expr,
3147            DatexExpression::RemoteExecution(
3148                Box::new(DatexExpression::Identifier("a".to_string())),
3149                Box::new(DatexExpression::Identifier("b".to_string()))
3150            )
3151        );
3152    }
3153
3154    #[test]
3155    fn remote_execution_complex() {
3156        let src = "a :: b + c * 2";
3157        let expr = parse_unwrap(src);
3158        assert_eq!(
3159            expr,
3160            DatexExpression::RemoteExecution(
3161                Box::new(DatexExpression::Identifier("a".to_string())),
3162                Box::new(DatexExpression::BinaryOperation(
3163                    BinaryOperator::Arithmetic(ArithmeticOperator::Add),
3164                    Box::new(DatexExpression::Identifier("b".to_string())),
3165                    Box::new(DatexExpression::BinaryOperation(
3166                        BinaryOperator::Arithmetic(
3167                            ArithmeticOperator::Multiply
3168                        ),
3169                        Box::new(DatexExpression::Identifier("c".to_string())),
3170                        Box::new(DatexExpression::Integer(Integer::from(2))),
3171                        None
3172                    )),
3173                    None
3174                )),
3175            )
3176        );
3177    }
3178
3179    #[test]
3180    fn remote_execution_statements() {
3181        let src = "a :: b; 1";
3182        let expr = parse_unwrap(src);
3183        assert_eq!(
3184            expr,
3185            DatexExpression::Statements(vec![
3186                Statement {
3187                    expression: DatexExpression::RemoteExecution(
3188                        Box::new(DatexExpression::Identifier("a".to_string())),
3189                        Box::new(DatexExpression::Identifier("b".to_string()))
3190                    ),
3191                    is_terminated: true,
3192                },
3193                Statement {
3194                    expression: DatexExpression::Integer(Integer::from(1)),
3195                    is_terminated: false,
3196                },
3197            ])
3198        );
3199    }
3200
3201    #[test]
3202    fn remote_execution_inline_statements() {
3203        let src = "a :: (1; 2 + 3)";
3204        let expr = parse_unwrap(src);
3205        assert_eq!(
3206            expr,
3207            DatexExpression::RemoteExecution(
3208                Box::new(DatexExpression::Identifier("a".to_string())),
3209                Box::new(DatexExpression::Statements(vec![
3210                    Statement {
3211                        expression: DatexExpression::Integer(Integer::from(1)),
3212                        is_terminated: true,
3213                    },
3214                    Statement {
3215                        expression: DatexExpression::BinaryOperation(
3216                            BinaryOperator::Arithmetic(ArithmeticOperator::Add),
3217                            Box::new(DatexExpression::Integer(Integer::from(
3218                                2
3219                            ))),
3220                            Box::new(DatexExpression::Integer(Integer::from(
3221                                3
3222                            ))),
3223                            None
3224                        ),
3225                        is_terminated: false,
3226                    },
3227                ])),
3228            )
3229        );
3230    }
3231
3232    #[test]
3233    fn named_slot() {
3234        let src = "#endpoint";
3235        let expr = parse_unwrap(src);
3236        assert_eq!(
3237            expr,
3238            DatexExpression::Slot(Slot::Named("endpoint".to_string()))
3239        );
3240    }
3241
3242    #[test]
3243    fn deref() {
3244        let src = "*x";
3245        let expr = parse_unwrap(src);
3246        assert_eq!(
3247            expr,
3248            DatexExpression::Deref(Box::new(DatexExpression::Identifier(
3249                "x".to_string()
3250            )))
3251        );
3252    }
3253
3254    #[test]
3255    fn deref_multiple() {
3256        let src = "**x";
3257        let expr = parse_unwrap(src);
3258        assert_eq!(
3259            expr,
3260            DatexExpression::Deref(Box::new(DatexExpression::Deref(Box::new(
3261                DatexExpression::Identifier("x".to_string())
3262            ))))
3263        );
3264    }
3265
3266    #[test]
3267    fn addressed_slot() {
3268        let src = "#123";
3269        let expr = parse_unwrap(src);
3270        assert_eq!(expr, DatexExpression::Slot(Slot::Addressed(123)));
3271    }
3272
3273    #[test]
3274    fn pointer_address() {
3275        // 3 bytes (internal)
3276        let src = "$123456";
3277        let expr = parse_unwrap(src);
3278        assert_eq!(
3279            expr,
3280            DatexExpression::PointerAddress(PointerAddress::Internal([
3281                0x12, 0x34, 0x56
3282            ]))
3283        );
3284
3285        // 5 bytes (local)
3286        let src = "$123456789A";
3287        let expr = parse_unwrap(src);
3288        assert_eq!(
3289            expr,
3290            DatexExpression::PointerAddress(PointerAddress::Local([
3291                0x12, 0x34, 0x56, 0x78, 0x9A
3292            ]))
3293        );
3294
3295        // 26 bytes (remote)
3296        let src = "$1234567890ABCDEF123456789000000000000000000000000042";
3297        let expr = parse_unwrap(src);
3298        assert_eq!(
3299            expr,
3300            DatexExpression::PointerAddress(PointerAddress::Remote([
3301                0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34,
3302                0x56, 0x78, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3303                0x00, 0x00, 0x00, 0x00, 0x00, 0x42
3304            ]))
3305        );
3306
3307        // other lengths are invalid
3308        let src = "$12";
3309        let res = parse(src);
3310        assert!(res.is_err());
3311    }
3312
3313    #[test]
3314    fn variable_add_assignment() {
3315        let src = "x += 42";
3316        let expr = parse_unwrap(src);
3317        assert_eq!(
3318            expr,
3319            DatexExpression::VariableAssignment(
3320                AssignmentOperator::AddAssign,
3321                None,
3322                "x".to_string(),
3323                Box::new(DatexExpression::Integer(Integer::from(42))),
3324            )
3325        );
3326    }
3327
3328    #[test]
3329    fn variable_sub_assignment() {
3330        let src = "x -= 42";
3331        let expr = parse_unwrap(src);
3332        assert_eq!(
3333            expr,
3334            DatexExpression::VariableAssignment(
3335                AssignmentOperator::SubtractAssign,
3336                None,
3337                "x".to_string(),
3338                Box::new(DatexExpression::Integer(Integer::from(42))),
3339            )
3340        );
3341    }
3342
3343    #[test]
3344    fn variable_declaration_mut() {
3345        let src = "const x = &mut [1, 2, 3]";
3346        let expr = parse_unwrap(src);
3347        assert_eq!(
3348            expr,
3349            DatexExpression::VariableDeclaration {
3350                id: None,
3351                kind: VariableKind::Const,
3352                name: "x".to_string(),
3353                type_annotation: None,
3354                init_expression: Box::new(DatexExpression::CreateRefMut(
3355                    Box::new(DatexExpression::List(vec![
3356                        DatexExpression::Integer(Integer::from(1)),
3357                        DatexExpression::Integer(Integer::from(2)),
3358                        DatexExpression::Integer(Integer::from(3)),
3359                    ]))
3360                )),
3361            }
3362        );
3363    }
3364
3365    #[test]
3366    fn variable_declaration_ref() {
3367        let src = "const x = &[1, 2, 3]";
3368        let expr = parse_unwrap(src);
3369        assert_eq!(
3370            expr,
3371            DatexExpression::VariableDeclaration {
3372                id: None,
3373                kind: VariableKind::Const,
3374                name: "x".to_string(),
3375                type_annotation: None,
3376                init_expression: Box::new(DatexExpression::CreateRef(
3377                    Box::new(DatexExpression::List(vec![
3378                        DatexExpression::Integer(Integer::from(1)),
3379                        DatexExpression::Integer(Integer::from(2)),
3380                        DatexExpression::Integer(Integer::from(3)),
3381                    ]))
3382                )),
3383            }
3384        );
3385    }
3386    #[test]
3387    fn variable_declaration() {
3388        let src = "const x = 1";
3389        let expr = parse_unwrap(src);
3390        assert_eq!(
3391            expr,
3392            DatexExpression::VariableDeclaration {
3393                id: None,
3394                kind: VariableKind::Const,
3395                name: "x".to_string(),
3396                type_annotation: None,
3397                init_expression: Box::new(DatexExpression::Integer(
3398                    Integer::from(1)
3399                )),
3400            }
3401        );
3402    }
3403
3404    #[test]
3405    fn negation() {
3406        let src = "!x";
3407        let expr = parse_unwrap(src);
3408        assert_eq!(
3409            expr,
3410            DatexExpression::UnaryOperation(
3411                UnaryOperator::Logical(LogicalUnaryOperator::Not),
3412                Box::new(DatexExpression::Identifier("x".to_string()))
3413            )
3414        );
3415
3416        let src = "!true";
3417        let expr = parse_unwrap(src);
3418        assert_eq!(
3419            expr,
3420            DatexExpression::UnaryOperation(
3421                UnaryOperator::Logical(LogicalUnaryOperator::Not),
3422                Box::new(DatexExpression::Boolean(true))
3423            )
3424        );
3425
3426        let src = "!![1, 2]";
3427        let expr = parse_unwrap(src);
3428        assert_matches!(
3429            expr,
3430            DatexExpression::UnaryOperation(
3431                UnaryOperator::Logical(LogicalUnaryOperator::Not),
3432                box DatexExpression::UnaryOperation(
3433                    UnaryOperator::Logical(LogicalUnaryOperator::Not),
3434                    box DatexExpression::List(_),
3435                ),
3436            )
3437        );
3438    }
3439}