coda_runtime/runtime/
value.rs1use 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}