1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#[derive(Debug, PartialEq)]
pub enum Expression {
    Number(f64),
    String(String),
    Boolean(bool),
    Array(Vec<Box<Expression>>),
    Object(Vec<(String, Box<Expression>)>),
    BinaryOperation {
        operation: OpCode,
        left: Box<Expression>,
        right: Box<Expression>,
    },
    Transform {
        name: String,
        subject: Box<Expression>,
        args: Option<Vec<Box<Expression>>>,
    },
    DotOperation {
        subject: Box<Expression>,
        ident: String,
    },
    IndexOperation {
        subject: Box<Expression>,
        index: Box<Expression>,
    },

    Identifier(String),
}

#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum OpCode {
    Add,
    Subtract,
    Multiply,
    Divide,
    FloorDivide,
    Less,
    LessEqual,
    Greater,
    GreaterEqual,
    Equal,
    NotEqual,
    And,
    Or,
    Modulus,
    Exponent,
    In,
}

impl std::fmt::Display for OpCode {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "{}",
            match self {
                OpCode::Add => "Add",
                OpCode::Subtract => "Subtract",
                OpCode::Multiply => "Multiply",
                OpCode::Divide => "Divide",
                OpCode::FloorDivide => "Floor division",
                OpCode::Less => "Less than",
                OpCode::LessEqual => "Less than or equal to",
                OpCode::Greater => "Greater than",
                OpCode::GreaterEqual => "Greater than or equal to",
                OpCode::Equal => "Equal",
                OpCode::NotEqual => "Not equal",
                OpCode::And => "Bitwise And",
                OpCode::Or => "Bitwise Or",
                OpCode::Modulus => "Modulus",
                OpCode::Exponent => "Exponent",
                OpCode::In => "In",
            }
        )
    }
}