1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
use std::collections::HashMap;
use super::types::Op;
use super::types::Op::*;
use super::types::SEXP;
use super::types::SEXP::*;
use super::types::Type::*;
use super::types::Number;
pub mod arith;
pub type Env = HashMap<String, SEXP>;
pub fn eval(expr: &SEXP, env: &mut Env) -> Result<SEXP, String> {
match expr {
Atom(ref x) => Ok(Atom((*x).clone())),
Sexpr(ref s) => seval(s, env)
}
}
fn seval(sexpr: &[SEXP], env: &mut Env) -> Result<SEXP, String> {
if sexpr.is_empty() {
return Err("Empty S Expression".to_string())
}
let op = match &sexpr[0] {
Atom(Operator(x)) => *x,
Atom(Symbol(_s)) => return Err("Not yet implemented".to_string()),
x => return Err(format!("{:?} is not a procedure", x))
};
op_eval(op, &sexpr[1..], env)
}
fn op_eval(op: Op, expr: &[SEXP], env: &mut Env) -> Result<SEXP, String> {
match op {
Add => op_add(expr, env),
//Define => define(expr, env),
_ => Err("Not yet implemented".to_string())
}
}
fn op_add(expr: &[SEXP], env: &mut Env) -> Result<SEXP, String> {
let mut acc = Number(Number::Int(0));
let mut i = 0;
while i < expr.len() {
let b = match eval(&expr[i], env)? {
Atom(x) => x,
Sexpr(_) => panic!("This should have evaluated to an atom")
};
acc = (acc + b)?;
i += 1;
}
Ok(SEXP::Atom(acc))
}
|