datex_core/ast/
assignment_operation.rs

1use std::fmt::Display;
2
3use crate::ast::DatexParserTrait;
4use crate::ast::lexer::Token;
5use crate::ast::utils::whitespace;
6use crate::global::instruction_codes::InstructionCode;
7use chumsky::prelude::*;
8
9#[derive(Clone, Debug, PartialEq, Copy)]
10pub enum AssignmentOperator {
11    Assign,           // =
12    AddAssign,        // +=
13    SubtractAssign,   // -=
14    MultiplyAssign,   // *=
15    DivideAssign,     // /=
16    ModuloAssign,     // %=
17    PowerAssign,      // ^=
18    BitwiseAndAssign, // &=
19    BitwiseOrAssign,  // |=
20}
21impl Display for AssignmentOperator {
22    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23        write!(
24            f,
25            "{}",
26            match self {
27                AssignmentOperator::Assign => "=",
28                AssignmentOperator::AddAssign => "+=",
29                AssignmentOperator::SubtractAssign => "-=",
30                AssignmentOperator::MultiplyAssign => "*=",
31                AssignmentOperator::DivideAssign => "/=",
32                AssignmentOperator::ModuloAssign => "%=",
33                AssignmentOperator::PowerAssign => "^=",
34                AssignmentOperator::BitwiseAndAssign => "&=",
35                AssignmentOperator::BitwiseOrAssign => "|=",
36            }
37        )
38    }
39}
40
41impl From<&AssignmentOperator> for InstructionCode {
42    fn from(op: &AssignmentOperator) -> Self {
43        match op {
44            AssignmentOperator::Assign => InstructionCode::ASSIGN,
45            AssignmentOperator::AddAssign => InstructionCode::ADD_ASSIGN,
46            AssignmentOperator::SubtractAssign => {
47                InstructionCode::SUBTRACT_ASSIGN
48            }
49            AssignmentOperator::MultiplyAssign => {
50                InstructionCode::MULTIPLY_ASSIGN
51            }
52            AssignmentOperator::DivideAssign => InstructionCode::DIVIDE_ASSIGN,
53            operator => todo!(
54                "Assignment operator {:?} not implemented for InstructionCode",
55                operator
56            ),
57        }
58    }
59}
60
61impl TryFrom<InstructionCode> for AssignmentOperator {
62    type Error = ();
63    fn try_from(code: InstructionCode) -> Result<Self, Self::Error> {
64        Ok(match code {
65            InstructionCode::ASSIGN => AssignmentOperator::Assign,
66            InstructionCode::ADD_ASSIGN => AssignmentOperator::AddAssign,
67            InstructionCode::SUBTRACT_ASSIGN => {
68                AssignmentOperator::SubtractAssign
69            }
70            InstructionCode::MULTIPLY_ASSIGN => {
71                AssignmentOperator::MultiplyAssign
72            }
73            InstructionCode::DIVIDE_ASSIGN => AssignmentOperator::DivideAssign,
74            _ => return Err(()),
75        })
76    }
77}
78
79pub fn assignment_operation<'a>()
80-> impl DatexParserTrait<'a, AssignmentOperator> {
81    select! {
82        Token::Assign      => AssignmentOperator::Assign,
83        Token::AddAssign   => AssignmentOperator::AddAssign,
84        Token::SubAssign   => AssignmentOperator::SubtractAssign,
85        Token::MulAssign   => AssignmentOperator::MultiplyAssign,
86        Token::DivAssign   => AssignmentOperator::DivideAssign,
87        Token::ModAssign   => AssignmentOperator::ModuloAssign,
88    }
89    .padded_by(whitespace())
90}