1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
5#[non_exhaustive]
6pub enum Expression {
7 String(String),
10 Integer(i64),
12 Float(f64),
14 Boolean(bool),
16 Nil,
18
19 Variable(String),
22 FieldAccess(Box<Expression>, String),
24 Index(Box<Expression>, Box<Expression>),
26
27 Call(String, Vec<Expression>),
30 MethodCall(Box<Expression>, String, Vec<Expression>),
32
33 Add(Box<Expression>, Box<Expression>),
36 Subtract(Box<Expression>, Box<Expression>),
38 Multiply(Box<Expression>, Box<Expression>),
40 Divide(Box<Expression>, Box<Expression>),
42 Modulo(Box<Expression>, Box<Expression>),
44 BitAnd(Box<Expression>, Box<Expression>),
46 BitOr(Box<Expression>, Box<Expression>),
48
49 Equal(Box<Expression>, Box<Expression>),
52 NotEqual(Box<Expression>, Box<Expression>),
54 LessThan(Box<Expression>, Box<Expression>),
56 LessEqual(Box<Expression>, Box<Expression>),
58 GreaterThan(Box<Expression>, Box<Expression>),
60 GreaterEqual(Box<Expression>, Box<Expression>),
62
63 And(Box<Expression>, Box<Expression>),
66 Or(Box<Expression>, Box<Expression>),
68 Not(Box<Expression>),
70
71 Assign(Box<Expression>, Box<Expression>),
74}
75
76impl Expression {
77 pub fn assign(path: &[&str], value: Expression) -> Self {
79 let (root, fields) = path
80 .split_first()
81 .expect("assignment path must not be empty");
82 let target = fields
83 .iter()
84 .fold(Expression::Variable(root.to_string()), |obj, field| {
85 Expression::FieldAccess(Box::new(obj), field.to_string())
86 });
87 Expression::Assign(Box::new(target), Box::new(value))
88 }
89
90 pub fn call(name: &str, args: Vec<Expression>) -> Self {
92 Expression::Call(name.to_string(), args)
93 }
94
95 pub fn is_assignable(&self) -> bool {
97 match self {
98 Expression::Variable(_) => true,
99 Expression::FieldAccess(inner, _) | Expression::Index(inner, _) => {
100 inner.is_assignable()
101 }
102 _ => false,
103 }
104 }
105}