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::Quote(inner) => quoted_to_value(inner),
25 Expr::List(_) => Ok(Value::String(format_expr(expr))),
26 Expr::Lambda(_, _) => Ok(Value::String(format_expr(expr))),
27 Expr::RuntimeValue(val) => Ok(val.clone()),
28 _ => Err(Error::Compile(format!("unsupported expression: {expr:?}"))),
29 }
30}
31
32fn quoted_to_value(inner: &Expr) -> Result<Value> {
33 match inner {
34 Expr::Nil => Ok(Value::Nil),
35 Expr::Bool(b) => Ok(Value::Bool(*b)),
36 Expr::Number(n) => Ok(Value::Number(*n)),
37 Expr::String(s) => Ok(Value::String(s.clone())),
38 Expr::Symbol(s) => Ok(Value::Symbol(s.clone())),
39 Expr::List(elems) => {
40 let inner: Vec<_> = elems.iter().map(format_expr).collect();
41 Ok(Value::String(format!("({})", inner.join(" "))))
42 }
43 _ => Err(Error::Compile(format!(
44 "unsupported quoted expression: {inner:?}"
45 ))),
46 }
47}