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 Literal(String),
124
125 Variable(VariableId, String),
126 GetReference(PointerAddress),
127
128 Integer(Integer),
130 TypedInteger(TypedInteger),
131 Decimal(Decimal),
132 TypedDecimal(TypedDecimal),
133 Boolean(bool),
134 Text(String),
135 Endpoint(Endpoint),
136
137 StructuralList(Vec<TypeExpression>),
140
141 FixedSizeList(Box<TypeExpression>, usize),
144
145 SliceList(Box<TypeExpression>),
148
149 Intersection(Vec<TypeExpression>),
151
152 Union(Vec<TypeExpression>),
154
155 Generic(String, Vec<TypeExpression>),
157
158 Function {
160 parameters: Vec<(String, TypeExpression)>,
161 return_type: Box<TypeExpression>,
162 },
163
164 StructuralMap(Vec<(TypeExpression, TypeExpression)>),
166
167 Ref(Box<TypeExpression>),
169 RefMut(Box<TypeExpression>),
170 RefFinal(Box<TypeExpression>),
171}
172
173#[derive(Clone, Debug, PartialEq)]
174pub enum DatexExpression {
175 Recover,
178
179 Null,
181 Boolean(bool),
183 Text(String),
185 Decimal(Decimal),
187
188 TypedDecimal(TypedDecimal),
190
191 Integer(Integer),
193
194 TypedInteger(TypedInteger),
196
197 Identifier(String),
199
200 Endpoint(Endpoint),
202 List(Vec<DatexExpression>),
204 Map(Vec<(DatexExpression, DatexExpression)>),
206 Statements(Vec<Statement>),
208 Variable(VariableId, String),
210 GetReference(PointerAddress),
212
213 Conditional {
215 condition: Box<DatexExpression>,
216 then_branch: Box<DatexExpression>,
217 else_branch: Option<Box<DatexExpression>>,
218 },
219
220 VariableDeclaration {
223 id: Option<VariableId>,
224 kind: VariableKind,
225 name: String,
226 type_annotation: Option<TypeExpression>,
227 init_expression: Box<DatexExpression>,
228 },
229
230 TypeDeclaration {
235 id: Option<VariableId>,
236 name: String,
237 value: TypeExpression, hoisted: bool,
239 },
240
241 TypeExpression(TypeExpression),
243
244 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 CreateRef(Box<DatexExpression>),
257 CreateRefMut(Box<DatexExpression>),
259 CreateRefFinal(Box<DatexExpression>),
261
262 Deref(Box<DatexExpression>),
264
265 Slot(Slot),
267 SlotAssignment(Slot, Box<DatexExpression>),
269
270 PointerAddress(PointerAddress),
271
272 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 ApplyChain(Box<DatexExpression>, Vec<ApplyOperation>),
300
301 Placeholder,
303 RemoteExecution(Box<DatexExpression>, Box<DatexExpression>),
305}
306
307impl 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 let mut inner_expression = Recursive::declare();
372
373 let mut expression = Recursive::declare();
375
376 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(), )
393 .map(|(exprs, last)| {
394 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 statements.push(Statement {
406 expression: last_expr,
407 is_terminated: last_semi.is_some(),
408 });
409 }
410 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 let wrapped_expression = statements
422 .clone()
423 .delimited_by(just(Token::LeftParen), just(Token::RightParen));
424 let key = key(wrapped_expression.clone()).labelled(Pattern::Custom("key"));
430
431 let list = list(expression.clone());
435
436 let map = map(key.clone(), expression.clone());
438
439 let atom = atom(list.clone(), map.clone(), wrapped_expression.clone());
441 let unary = unary(atom.clone());
442
443 let chain =
445 chain(unary.clone(), key.clone(), atom.clone(), expression.clone());
446
447 let binary = binary_operation(chain);
448
449 let function_declaration = function(statements.clone());
451
452 let comparison = comparison_operation(binary.clone());
454
455 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 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 just(Token::Semicolon)
530 .repeated()
531 .at_least(1)
532 .padded_by(whitespace())
533 .map(|_| DatexExpression::Statements(vec![])),
534 statements,
536 ))
537}
538
539pub fn parse(mut src: &str) -> Result<DatexExpression, Vec<ParseError>> {
540 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 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 #[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 }
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 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 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 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 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 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 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 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 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 #[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 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 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 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 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 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}