tcss_core/
executor.rs

1//! Expression executor for TCSS
2//!
3//! This module evaluates expressions and executes TCSS programs.
4
5use crate::ast::{ASTNode, BinaryOp, Expr, Program, Statement};
6use crate::context::{Context, Value};
7use crate::builtins;
8use std::collections::HashMap;
9
10/// Executor for TCSS programs
11pub struct Executor {
12    context: Context,
13}
14
15impl Executor {
16    /// Create a new executor
17    pub fn new() -> Self {
18        Self {
19            context: Context::new(),
20        }
21    }
22
23    /// Execute a TCSS program
24    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    /// Execute a single AST node
32    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                // Import handling will be implemented in Phase 10
45                Ok(())
46            }
47            ASTNode::CSSRule { .. } => {
48                // CSS rules are not executed, just stored in AST
49                Ok(())
50            }
51        }
52    }
53
54    /// Evaluate an expression
55    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    /// Evaluate a binary operation
101    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    /// Evaluate a function call
121    fn evaluate_function_call(&mut self, name: &str, args: &[Expr]) -> Result<Value, String> {
122        // Evaluate arguments
123        let mut arg_values = Vec::new();
124        for arg in args {
125            arg_values.push(self.evaluate_expr(arg)?);
126        }
127
128        // Check if it's a built-in function first
129        if builtins::is_builtin(name) {
130            return builtins::call_builtin(name, &arg_values);
131        }
132
133        // Get user-defined function
134        let func = self.context.get_function(name)
135            .ok_or_else(|| format!("Undefined function: {}", name))?
136            .clone();
137
138        // Check parameter count
139        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        // Create new scope for function execution
149        self.context.push_scope();
150
151        // Bind parameters to arguments
152        for (param, value) in func.params.iter().zip(arg_values.iter()) {
153            self.context.set_variable(param.clone(), value.clone());
154        }
155
156        // Execute function body
157        let mut result = Value::Null;
158        for stmt in &func.body {
159            result = self.execute_statement(stmt)?;
160            // If we hit a return statement, break
161            if matches!(stmt, Statement::Return(_)) {
162                break;
163            }
164        }
165
166        // Pop function scope
167        self.context.pop_scope();
168
169        Ok(result)
170    }
171
172    /// Execute a statement
173    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    /// Add two values
186    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    /// Subtract two values
208    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    /// Multiply two values
226    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    /// Divide two values
238    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    /// Modulo operation
268    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    /// Check if two values are equal
282    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    /// Compare two values
297    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    /// Get the current context (for testing/debugging)
315    pub fn context(&self) -> &Context {
316        &self.context
317    }
318
319    /// Get a mutable reference to the context
320    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