1use crate::ast::{Expr, Program};
2use crate::compiler::expr::{eval_value, format_expr};
3use crate::error::{Error, Result};
4use crate::runtime::{SymbolTable, Value};
5
6pub fn eval_program(symbols: &mut SymbolTable, program: &Program) -> Result<Value> {
7 if program.exprs.is_empty() {
8 return Ok(Value::Nil);
9 }
10 for expr in &program.exprs[..program.exprs.len() - 1] {
11 eval_value(symbols, expr)?;
12 }
13 let value = eval_value(symbols, program.exprs.last().unwrap())?;
14 expr_to_value(&value)
15}
16
17fn expr_to_value(expr: &Expr) -> Result<Value> {
18 match expr {
19 Expr::Nil => Ok(Value::Nil),
20 Expr::Bool(b) => Ok(Value::Bool(*b)),
21 Expr::Number(n) => Ok(Value::Number(*n)),
22 Expr::String(s) => Ok(Value::String(s.clone())),
23 Expr::Symbol(s) => Ok(Value::Symbol(s.clone())),
24 Expr::Bytes(b) => Ok(Value::Bytes(b.clone())),
25 Expr::Quote(inner) => quoted_to_value(inner),
26 Expr::List(_) => Ok(Value::String(format_expr(expr))),
27 Expr::Lambda(_, _) => Ok(Value::String(format_expr(expr))),
28 Expr::RuntimeValue(val) => Ok(val.clone()),
29 _ => Err(Error::Compile(format!("unsupported expression: {expr:?}"))),
30 }
31}
32
33fn quoted_to_value(inner: &Expr) -> Result<Value> {
34 match inner {
35 Expr::Nil => Ok(Value::Nil),
36 Expr::Bool(b) => Ok(Value::Bool(*b)),
37 Expr::Number(n) => Ok(Value::Number(*n)),
38 Expr::String(s) => Ok(Value::String(s.clone())),
39 Expr::Symbol(s) => Ok(Value::Symbol(s.clone())),
40 Expr::Bytes(b) => Ok(Value::Bytes(b.clone())),
41 Expr::List(elems) => {
42 let inner: Vec<_> = elems.iter().map(format_expr).collect();
43 Ok(Value::String(format!("({})", inner.join(" "))))
44 }
45 _ => Err(Error::Compile(format!(
46 "unsupported quoted expression: {inner:?}"
47 ))),
48 }
49}