1use crate::ast::{ASTNode, BinaryOp, Expr, Program, Statement};
6use crate::context::{Context, Value};
7use crate::builtins;
8use std::collections::HashMap;
9
10pub struct Executor {
12 context: Context,
13}
14
15impl Executor {
16 pub fn new() -> Self {
18 Self {
19 context: Context::new(),
20 }
21 }
22
23 pub fn execute(&mut self, program: &Program) -> Result<(), String> {
25 for node in &program.nodes {
26 self.execute_node(node)?;
27 }
28 Ok(())
29 }
30
31 fn execute_node(&mut self, node: &ASTNode) -> Result<(), String> {
33 match node {
34 ASTNode::Function { name, params, body } => {
35 self.context.define_function(name.clone(), params.clone(), body.clone());
36 Ok(())
37 }
38 ASTNode::Variable { name, value } => {
39 let val = self.evaluate_expr(value)?;
40 self.context.set_variable(name.clone(), val);
41 Ok(())
42 }
43 ASTNode::Import { .. } => {
44 Ok(())
46 }
47 ASTNode::CSSRule { .. } => {
48 Ok(())
50 }
51 }
52 }
53
54 pub fn evaluate_expr(&mut self, expr: &Expr) -> Result<Value, String> {
56 match expr {
57 Expr::Literal(s) => Ok(Value::String(s.clone())),
58
59 Expr::Number(n) => Ok(Value::Number(*n)),
60
61 Expr::Unit { value, unit } => Ok(Value::Unit {
62 value: *value,
63 unit: unit.clone(),
64 }),
65
66 Expr::Color(c) => Ok(Value::Color(c.clone())),
67
68 Expr::Variable(name) => {
69 self.context.get_variable(name)
70 .ok_or_else(|| format!("Undefined variable: {}", name))
71 }
72
73 Expr::Binary { op, left, right } => {
74 self.evaluate_binary(*op, left, right)
75 }
76
77 Expr::FunctionCall { name, args } => {
78 self.evaluate_function_call(name, args)
79 }
80
81 Expr::Array(elements) => {
82 let mut values = Vec::new();
83 for elem in elements {
84 values.push(self.evaluate_expr(elem)?);
85 }
86 Ok(Value::Array(values))
87 }
88
89 Expr::Object(pairs) => {
90 let mut map = HashMap::new();
91 for (key, value_expr) in pairs {
92 let value = self.evaluate_expr(value_expr)?;
93 map.insert(key.clone(), value);
94 }
95 Ok(Value::Object(map))
96 }
97 }
98 }
99
100 fn evaluate_binary(&mut self, op: BinaryOp, left: &Expr, right: &Expr) -> Result<Value, String> {
102 let left_val = self.evaluate_expr(left)?;
103 let right_val = self.evaluate_expr(right)?;
104
105 match op {
106 BinaryOp::Add => self.add_values(left_val, right_val),
107 BinaryOp::Subtract => self.subtract_values(left_val, right_val),
108 BinaryOp::Multiply => self.multiply_values(left_val, right_val),
109 BinaryOp::Divide => self.divide_values(left_val, right_val),
110 BinaryOp::Modulo => self.modulo_values(left_val, right_val),
111 BinaryOp::Equal => Ok(Value::Boolean(self.values_equal(&left_val, &right_val))),
112 BinaryOp::NotEqual => Ok(Value::Boolean(!self.values_equal(&left_val, &right_val))),
113 BinaryOp::Less => self.compare_values(left_val, right_val, |a, b| a < b),
114 BinaryOp::Greater => self.compare_values(left_val, right_val, |a, b| a > b),
115 BinaryOp::LessEqual => self.compare_values(left_val, right_val, |a, b| a <= b),
116 BinaryOp::GreaterEqual => self.compare_values(left_val, right_val, |a, b| a >= b),
117 }
118 }
119
120 fn evaluate_function_call(&mut self, name: &str, args: &[Expr]) -> Result<Value, String> {
122 let mut arg_values = Vec::new();
124 for arg in args {
125 arg_values.push(self.evaluate_expr(arg)?);
126 }
127
128 if builtins::is_builtin(name) {
130 return builtins::call_builtin(name, &arg_values);
131 }
132
133 let func = self.context.get_function(name)
135 .ok_or_else(|| format!("Undefined function: {}", name))?
136 .clone();
137
138 if func.params.len() != arg_values.len() {
140 return Err(format!(
141 "Function {} expects {} arguments, got {}",
142 name,
143 func.params.len(),
144 arg_values.len()
145 ));
146 }
147
148 self.context.push_scope();
150
151 for (param, value) in func.params.iter().zip(arg_values.iter()) {
153 self.context.set_variable(param.clone(), value.clone());
154 }
155
156 let mut result = Value::Null;
158 for stmt in &func.body {
159 result = self.execute_statement(stmt)?;
160 if matches!(stmt, Statement::Return(_)) {
162 break;
163 }
164 }
165
166 self.context.pop_scope();
168
169 Ok(result)
170 }
171
172 fn execute_statement(&mut self, stmt: &Statement) -> Result<Value, String> {
174 match stmt {
175 Statement::Return(expr) => self.evaluate_expr(expr),
176 Statement::Assignment { name, value } => {
177 let val = self.evaluate_expr(value)?;
178 self.context.set_variable(name.clone(), val.clone());
179 Ok(val)
180 }
181 Statement::Expression(expr) => self.evaluate_expr(expr),
182 }
183 }
184
185 fn add_values(&self, left: Value, right: Value) -> Result<Value, String> {
187 match (left, right) {
188 (Value::Number(a), Value::Number(b)) => Ok(Value::Number(a + b)),
189 (Value::Unit { value: a, unit: u1 }, Value::Unit { value: b, unit: u2 }) => {
190 if u1 == u2 {
191 Ok(Value::Unit { value: a + b, unit: u1 })
192 } else {
193 Err(format!("Cannot add units {} and {}", u1, u2))
194 }
195 }
196 (Value::Number(a), Value::Unit { value: b, unit }) |
197 (Value::Unit { value: b, unit }, Value::Number(a)) => {
198 Ok(Value::Unit { value: a + b, unit })
199 }
200 (Value::String(a), Value::String(b)) => Ok(Value::String(format!("{}{}", a, b))),
201 (Value::String(a), b) => Ok(Value::String(format!("{}{}", a, b.to_css_string()))),
202 (a, Value::String(b)) => Ok(Value::String(format!("{}{}", a.to_css_string(), b))),
203 _ => Err("Cannot add these types".to_string()),
204 }
205 }
206
207 fn subtract_values(&self, left: Value, right: Value) -> Result<Value, String> {
209 match (left, right) {
210 (Value::Number(a), Value::Number(b)) => Ok(Value::Number(a - b)),
211 (Value::Unit { value: a, unit: u1 }, Value::Unit { value: b, unit: u2 }) => {
212 if u1 == u2 {
213 Ok(Value::Unit { value: a - b, unit: u1 })
214 } else {
215 Err(format!("Cannot subtract units {} and {}", u1, u2))
216 }
217 }
218 (Value::Unit { value: a, unit }, Value::Number(b)) => {
219 Ok(Value::Unit { value: a - b, unit })
220 }
221 _ => Err("Cannot subtract these types".to_string()),
222 }
223 }
224
225 fn multiply_values(&self, left: Value, right: Value) -> Result<Value, String> {
227 match (left, right) {
228 (Value::Number(a), Value::Number(b)) => Ok(Value::Number(a * b)),
229 (Value::Number(a), Value::Unit { value: b, unit }) |
230 (Value::Unit { value: b, unit }, Value::Number(a)) => {
231 Ok(Value::Unit { value: a * b, unit })
232 }
233 _ => Err("Cannot multiply these types".to_string()),
234 }
235 }
236
237 fn divide_values(&self, left: Value, right: Value) -> Result<Value, String> {
239 match (left, right) {
240 (Value::Number(a), Value::Number(b)) => {
241 if b == 0.0 {
242 Err("Division by zero".to_string())
243 } else {
244 Ok(Value::Number(a / b))
245 }
246 }
247 (Value::Unit { value: a, unit }, Value::Number(b)) => {
248 if b == 0.0 {
249 Err("Division by zero".to_string())
250 } else {
251 Ok(Value::Unit { value: a / b, unit })
252 }
253 }
254 (Value::Unit { value: a, unit: u1 }, Value::Unit { value: b, unit: u2 }) => {
255 if b == 0.0 {
256 Err("Division by zero".to_string())
257 } else if u1 == u2 {
258 Ok(Value::Number(a / b))
259 } else {
260 Err(format!("Cannot divide units {} and {}", u1, u2))
261 }
262 }
263 _ => Err("Cannot divide these types".to_string()),
264 }
265 }
266
267 fn modulo_values(&self, left: Value, right: Value) -> Result<Value, String> {
269 match (left, right) {
270 (Value::Number(a), Value::Number(b)) => {
271 if b == 0.0 {
272 Err("Modulo by zero".to_string())
273 } else {
274 Ok(Value::Number(a % b))
275 }
276 }
277 _ => Err("Cannot perform modulo on these types".to_string()),
278 }
279 }
280
281 fn values_equal(&self, left: &Value, right: &Value) -> bool {
283 match (left, right) {
284 (Value::Number(a), Value::Number(b)) => (a - b).abs() < f64::EPSILON,
285 (Value::String(a), Value::String(b)) => a == b,
286 (Value::Color(a), Value::Color(b)) => a == b,
287 (Value::Boolean(a), Value::Boolean(b)) => a == b,
288 (Value::Unit { value: a, unit: u1 }, Value::Unit { value: b, unit: u2 }) => {
289 u1 == u2 && (a - b).abs() < f64::EPSILON
290 }
291 (Value::Null, Value::Null) => true,
292 _ => false,
293 }
294 }
295
296 fn compare_values<F>(&self, left: Value, right: Value, op: F) -> Result<Value, String>
298 where
299 F: Fn(f64, f64) -> bool,
300 {
301 match (left, right) {
302 (Value::Number(a), Value::Number(b)) => Ok(Value::Boolean(op(a, b))),
303 (Value::Unit { value: a, unit: u1 }, Value::Unit { value: b, unit: u2 }) => {
304 if u1 == u2 {
305 Ok(Value::Boolean(op(a, b)))
306 } else {
307 Err(format!("Cannot compare units {} and {}", u1, u2))
308 }
309 }
310 _ => Err("Cannot compare these types".to_string()),
311 }
312 }
313
314 pub fn context(&self) -> &Context {
316 &self.context
317 }
318
319 pub fn context_mut(&mut self) -> &mut Context {
321 &mut self.context
322 }
323}
324
325impl Default for Executor {
326 fn default() -> Self {
327 Self::new()
328 }
329}
330