Skip to main content

nomiscript/
eval.rs

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}