1use rimu_meta::Spanned;
2use rust_decimal::Decimal;
3use std::fmt;
4
5use crate::{BinaryOperator, UnaryOperator};
6
7#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
9pub enum Expression {
10 Null,
12
13 Boolean(bool),
15
16 String(String),
18
19 Number(Decimal),
21
22 Identifier(String),
24
25 List(Vec<SpannedExpression>),
27
28 Object(Vec<(Spanned<String>, SpannedExpression)>),
30
31 Function {
33 args: Vec<Spanned<String>>,
34 body: Box<SpannedExpression>,
35 },
36
37 Unary {
39 right: Box<SpannedExpression>,
40 operator: UnaryOperator,
41 },
42
43 Binary {
45 left: Box<SpannedExpression>,
46 right: Box<SpannedExpression>,
47 operator: BinaryOperator,
48 },
49
50 Call {
52 function: Box<SpannedExpression>,
53 args: Vec<SpannedExpression>,
54 },
55
56 GetIndex {
58 container: Box<SpannedExpression>,
59 index: Box<SpannedExpression>,
60 },
61
62 GetKey {
64 container: Box<SpannedExpression>,
65 key: Spanned<String>,
66 },
67
68 GetSlice {
70 container: Box<SpannedExpression>,
71 start: Option<Box<SpannedExpression>>,
72 end: Option<Box<SpannedExpression>>,
73 },
74
75 Error,
76}
77
78pub type SpannedExpression = Spanned<Expression>;
79
80impl fmt::Display for Expression {
81 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82 match self {
83 Expression::Null => write!(f, "null"),
84 Expression::Boolean(boolean) => write!(f, "{}", boolean),
85 Expression::String(string) => write!(f, "\"{}\"", string),
86 Expression::Number(number) => write!(f, "{}", number),
87 Expression::List(list) => {
88 let keys = list
89 .iter()
90 .map(ToString::to_string)
91 .collect::<Vec<String>>()
92 .join(", ");
93 write!(f, "[{}]", keys)
94 }
95 Expression::Function { args, body } => {
96 let args = args
97 .iter()
98 .map(ToString::to_string)
99 .collect::<Vec<String>>()
100 .join(", ");
101 write!(f, "({}) => {}", args, body)
102 }
103 Expression::Object(object) => {
104 let entries = object
105 .iter()
106 .map(|(key, value)| format!("\"{}\": {}", key, value))
107 .collect::<Vec<String>>()
108 .join(", ");
109 write!(f, "{{{}}}", entries)
110 }
111 Expression::Identifier(identifier) => write!(f, "{}", identifier),
112 Expression::Unary { right, operator } => write!(f, "{}{}", operator, right),
113 Expression::Binary {
114 left,
115 operator,
116 right,
117 } => write!(f, "{} {} {}", left, operator, right),
118 Expression::Call { function, args } => {
119 let args = args
120 .iter()
121 .map(ToString::to_string)
122 .collect::<Vec<String>>()
123 .join(", ");
124 write!(f, "{}({})", function, args)
125 }
126 Expression::GetIndex { container, index } => write!(f, "{}[{}]", container, index),
127 Expression::GetKey { container, key } => write!(f, "{}.{}", container, key),
128 Expression::GetSlice {
129 container,
130 start,
131 end,
132 } => write!(
133 f,
134 "{}[{}:{}]",
135 container,
136 start.as_ref().map(|s| s.to_string()).unwrap_or("".into()),
137 end.as_ref().map(|e| e.to_string()).unwrap_or("".into()),
138 ),
139 Expression::Error => write!(f, "error"),
140 }
141 }
142}