datex_core/ast/
comparison_operation.rs1use std::fmt::Display;
2
3use crate::ast::DatexExpression;
4use crate::ast::DatexParserTrait;
5use crate::ast::lexer::Token;
6use crate::ast::utils::operation;
7use crate::global::instruction_codes::InstructionCode;
8use crate::global::protocol_structures::instructions::Instruction;
9use chumsky::prelude::*;
10
11#[derive(Clone, Debug, PartialEq, Copy)]
12pub enum ComparisonOperator {
13 Is, Matches, StructuralEqual, NotStructuralEqual, Equal, NotEqual, LessThan, GreaterThan, LessThanOrEqual, GreaterThanOrEqual, }
24
25impl Display for ComparisonOperator {
26 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27 write!(
28 f,
29 "{}",
30 match self {
31 ComparisonOperator::Is => "is",
32 ComparisonOperator::Matches => "matches",
33 ComparisonOperator::StructuralEqual => "==",
34 ComparisonOperator::NotStructuralEqual => "!=",
35 ComparisonOperator::Equal => "===",
36 ComparisonOperator::NotEqual => "!==",
37 ComparisonOperator::LessThan => "<",
38 ComparisonOperator::GreaterThan => ">",
39 ComparisonOperator::LessThanOrEqual => "<=",
40 ComparisonOperator::GreaterThanOrEqual => ">=",
41 }
42 )
43 }
44}
45
46fn comparison_op(
47 op: ComparisonOperator,
48) -> impl Fn(Box<DatexExpression>, Box<DatexExpression>) -> DatexExpression + Clone
49{
50 move |lhs, rhs| DatexExpression::ComparisonOperation(op, lhs, rhs)
51}
52
53pub fn comparison_operation<'a>(
54 union: impl DatexParserTrait<'a>,
55) -> impl DatexParserTrait<'a> {
56 union
57 .clone()
58 .foldl(
59 choice((
60 operation(Token::StructuralEqual)
61 .to(comparison_op(ComparisonOperator::StructuralEqual)),
62 operation(Token::Equal)
63 .to(comparison_op(ComparisonOperator::Equal)),
64 operation(Token::NotStructuralEqual)
65 .to(comparison_op(ComparisonOperator::NotStructuralEqual)),
66 operation(Token::NotEqual)
67 .to(comparison_op(ComparisonOperator::NotEqual)),
68 operation(Token::Is).to(comparison_op(ComparisonOperator::Is)),
69 operation(Token::Matches)
70 .to(comparison_op(ComparisonOperator::Matches)),
71 ))
72 .then(union.clone())
73 .repeated(),
74 |lhs, (op, rhs)| op(Box::new(lhs), Box::new(rhs)),
75 )
76 .boxed()
77}
78
79impl From<&ComparisonOperator> for InstructionCode {
80 fn from(op: &ComparisonOperator) -> Self {
81 match op {
82 ComparisonOperator::StructuralEqual => {
83 InstructionCode::STRUCTURAL_EQUAL
84 }
85 ComparisonOperator::NotStructuralEqual => {
86 InstructionCode::NOT_STRUCTURAL_EQUAL
87 }
88 ComparisonOperator::Equal => InstructionCode::EQUAL,
89 ComparisonOperator::NotEqual => InstructionCode::NOT_EQUAL,
90 ComparisonOperator::Is => InstructionCode::IS,
91 ComparisonOperator::Matches => InstructionCode::MATCHES,
92 operator => todo!(
93 "Comparison operator {:?} not implemented for InstructionCode",
94 operator
95 ),
96 }
97 }
98}
99
100impl From<ComparisonOperator> for InstructionCode {
101 fn from(op: ComparisonOperator) -> Self {
102 InstructionCode::from(&op)
103 }
104}
105impl From<&Instruction> for ComparisonOperator {
106 fn from(instruction: &Instruction) -> Self {
107 match instruction {
108 Instruction::StructuralEqual => ComparisonOperator::StructuralEqual,
109 Instruction::Equal => ComparisonOperator::Equal,
110 Instruction::NotStructuralEqual => {
111 ComparisonOperator::NotStructuralEqual
112 }
113 Instruction::NotEqual => ComparisonOperator::NotEqual,
114 Instruction::Is => ComparisonOperator::Is,
115 Instruction::Matches => ComparisonOperator::Matches,
116 _ => {
117 todo!(
118 "Comparison operator for instruction {:?} not implemented",
119 instruction
120 );
121 }
122 }
123 }
124}
125
126impl From<Instruction> for ComparisonOperator {
127 fn from(instruction: Instruction) -> Self {
128 ComparisonOperator::from(&instruction)
129 }
130}