Skip to main content

coda_runtime/runtime/
value.rs

1use crate::{runtime::{ast::Stmt, interpreter::Interpreter}, env::Env};
2use std::{cell::RefCell, rc::Rc};
3
4#[derive(Clone, Debug)]
5pub enum Value {
6    Number(f64),
7    String(String),
8    Bool(bool),
9    Null,
10    Array(Vec<Value>),
11
12    NativeFunction(fn(Vec<Value>) -> Value),
13    Function(Function),
14}
15
16impl Value {
17    pub fn as_bool(&self) -> bool {
18        match self {
19            Value::Bool(b) => *b,
20            Value::Null => false,
21            Value::Number(n) => *n != 0.0,
22            Value::String(s) => !s.is_empty(),
23            _ => true,
24        }
25    }
26}
27
28#[derive(Clone, Debug)]
29pub struct Function {
30    pub name: String,
31    pub params: Vec<String>,
32    pub body: Vec<Stmt>,
33    pub closure: Rc<RefCell<Env>>,
34}
35
36pub struct CodaFunction {
37    pub params: Vec<String>,
38    pub body: Vec<Stmt>,
39    pub closure: Rc<RefCell<Env>>,
40}
41
42impl CodaFunction {
43    pub fn call(&self, interpreter: &mut Interpreter, args: Vec<Value>) -> Value {
44        let new_env = Rc::new(RefCell::new(Env::new_with_parent(Some(self.closure.clone()))));
45
46        for (param, arg) in self.params.iter().zip(args) {
47            new_env.borrow_mut().define(param.clone(), arg);
48        }
49
50        let previous = interpreter.env.clone();
51
52        interpreter.env = new_env;
53
54        for stmt in &self.body {
55            let _ = interpreter.execute(stmt.clone());
56        }
57
58        interpreter.env = previous;
59
60        Value::Null
61    }
62}