1
use crate::ast::{Expr, Program};
2
use crate::compiler::expr::{eval_value, format_expr};
3
use crate::error::{Error, Result};
4
use crate::runtime::{SymbolTable, Value};
5

            
6
7802
pub fn eval_program(symbols: &mut SymbolTable, program: &Program) -> Result<Value> {
7
7802
    if program.exprs.is_empty() {
8
        return Ok(Value::Nil);
9
7802
    }
10
7968
    for expr in &program.exprs[..program.exprs.len() - 1] {
11
7968
        eval_value(symbols, expr)?;
12
    }
13
7802
    let value = eval_value(symbols, program.exprs.last().unwrap())?;
14
6972
    expr_to_value(&value)
15
7802
}
16

            
17
6972
fn expr_to_value(expr: &Expr) -> Result<Value> {
18
6972
    match expr {
19
664
        Expr::Nil => Ok(Value::Nil),
20
1577
        Expr::T => Ok(Value::T),
21
1992
        Expr::Number(n) => Ok(Value::Number(*n)),
22
249
        Expr::String(s) => Ok(Value::String(s.clone())),
23
83
        Expr::Symbol(s) => Ok(Value::Symbol(s.clone())),
24
        Expr::Bytes(b) => Ok(Value::Bytes(b.clone())),
25
1909
        Expr::Quote(inner) => quoted_to_value(inner),
26
166
        Expr::List(_) => Ok(Value::String(format_expr(expr))),
27
        Expr::Lambda(_, _) => Ok(Value::String(format_expr(expr))),
28
249
        Expr::RuntimeValue(val) => Ok(val.clone()),
29
83
        _ => Err(Error::Compile(format!("unsupported expression: {expr:?}"))),
30
    }
31
6972
}
32

            
33
1909
fn quoted_to_value(inner: &Expr) -> Result<Value> {
34
1909
    match inner {
35
        Expr::Nil => Ok(Value::Nil),
36
        Expr::T => Ok(Value::T),
37
        Expr::Number(n) => Ok(Value::Number(*n)),
38
        Expr::String(s) => Ok(Value::String(s.clone())),
39
664
        Expr::Symbol(s) => Ok(Value::Symbol(s.clone())),
40
83
        Expr::Bytes(b) => Ok(Value::Bytes(b.clone())),
41
1162
        Expr::List(_) | Expr::Cons(_, _) => Ok(Value::String(format_expr(inner))),
42
        _ => Err(Error::Compile(format!(
43
            "unsupported quoted expression: {inner:?}"
44
        ))),
45
    }
46
1909
}