Refactoring
This commit is contained in:
parent
18a839bb91
commit
3386fcc505
@ -71,14 +71,12 @@ impl EvaluatorState {
|
|||||||
fn eval(&mut self, expr: Sexp) -> Result<Sexp, String> {
|
fn eval(&mut self, expr: Sexp) -> Result<Sexp, String> {
|
||||||
use self::Sexp::*;
|
use self::Sexp::*;
|
||||||
Ok(match expr {
|
Ok(match expr {
|
||||||
SymbolAtom(ref sym) => {
|
SymbolAtom(ref sym) => match self.get_var(sym) {
|
||||||
match self.get_var(sym) {
|
Some(ref sexp) => {
|
||||||
Some(ref sexp) => {
|
let q: &Sexp = sexp; //WTF? if I delete this line, the copy doesn't work??
|
||||||
let q: &Sexp = sexp; //WTF? if I delete this line, the copy doesn't work??
|
q.clone() //TODO make this not involve a clone
|
||||||
q.clone() //TODO make this not involve a clone
|
},
|
||||||
},
|
None => return Err(format!("Variable {} not bound", sym)),
|
||||||
None => return Err(format!("Variable {} not bound", sym)),
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
expr @ StringAtom(_) => expr,
|
expr @ StringAtom(_) => expr,
|
||||||
expr @ NumberAtom(_) => expr,
|
expr @ NumberAtom(_) => expr,
|
||||||
@ -86,70 +84,85 @@ impl EvaluatorState {
|
|||||||
False => False,
|
False => False,
|
||||||
Cons(box operator, box operands) => {
|
Cons(box operator, box operands) => {
|
||||||
match operator {
|
match operator {
|
||||||
SymbolAtom(ref sym) => match &sym[..] {
|
SymbolAtom(sym) => match &sym[..] {
|
||||||
"quote" => operands,
|
"quote" | "eq?" | "cons" | "car" | "cdr" | "atom?" |
|
||||||
"eq?" => match operands {
|
"define" | "lambda" | "if" | "cond" => self.eval_special_form(&sym[..], operands)?,
|
||||||
Cons(box lhs, box Cons(box rhs, _)) => {
|
_ => {
|
||||||
match lhs == rhs {
|
let evaled = self.eval(SymbolAtom(sym))?;
|
||||||
true => True,
|
self.apply(evaled, operands)?
|
||||||
false => False,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => True,
|
|
||||||
},
|
|
||||||
"cons" => match operands {
|
|
||||||
Cons(box cadr, box Cons(box caddr, box Nil)) => {
|
|
||||||
let newl = self.eval(cadr)?;
|
|
||||||
let newr = self.eval(caddr)?;
|
|
||||||
Cons(Box::new(newl), Box::new(newr))
|
|
||||||
},
|
|
||||||
_ => return Err(format!("Bad arguments for cons")),
|
|
||||||
},
|
|
||||||
"car" => match operands {
|
|
||||||
Cons(box car, _) => car,
|
|
||||||
_ => return Err(format!("called car with a non-pair argument")),
|
|
||||||
},
|
|
||||||
"cdr" => match operands {
|
|
||||||
Cons(_, box cdr) => cdr,
|
|
||||||
_ => return Err(format!("called cdr with a non-pair argument")),
|
|
||||||
},
|
|
||||||
"atom?" => match operands {
|
|
||||||
Cons(_, _) => False,
|
|
||||||
_ => True,
|
|
||||||
},
|
|
||||||
"define" => match operands {
|
|
||||||
Cons(box SymbolAtom(sym), box Cons(box expr, box Nil)) => {
|
|
||||||
let evaluated = self.eval(expr)?;
|
|
||||||
self.set_var(sym, evaluated);
|
|
||||||
Nil
|
|
||||||
},
|
|
||||||
_ => return Err(format!("Bad assignment")),
|
|
||||||
}
|
}
|
||||||
"lambda" => match operands {
|
|
||||||
Cons(box paramlist, box Cons(box formalexp, box Nil)) => {
|
|
||||||
unimplemented!() //needs to return an abstract object
|
|
||||||
},
|
|
||||||
_ => return Err(format!("Bad lambda expression")),
|
|
||||||
},
|
|
||||||
"if" => match operands {
|
|
||||||
Cons(box test, box body) => {
|
|
||||||
let truth_value = test.truthy();
|
|
||||||
match (truth_value, body) {
|
|
||||||
(true, Cons(box consequent, _)) => consequent,
|
|
||||||
(false, Cons(_, box Cons(box alternative, _))) => alternative,
|
|
||||||
_ => return Err(format!("Bad if expression"))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => return Err(format!("Bad if expression"))
|
|
||||||
},
|
|
||||||
_ => unimplemented!(),
|
|
||||||
},
|
},
|
||||||
other => {println!("OTHER? {:?}", other); unimplemented!() }
|
_ => unimplemented!()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Nil => Nil,
|
Nil => Nil,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
fn eval_special_form(&mut self, form: &str, operands: Sexp) -> Result<Sexp, String> {
|
||||||
|
use self::Sexp::*;
|
||||||
|
Ok(match form {
|
||||||
|
"quote" => operands,
|
||||||
|
"eq?" => match operands {
|
||||||
|
Cons(box lhs, box Cons(box rhs, _)) => {
|
||||||
|
match lhs == rhs {
|
||||||
|
true => True,
|
||||||
|
false => False,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => True,
|
||||||
|
},
|
||||||
|
"cons" => match operands {
|
||||||
|
Cons(box cadr, box Cons(box caddr, box Nil)) => {
|
||||||
|
let newl = self.eval(cadr)?;
|
||||||
|
let newr = self.eval(caddr)?;
|
||||||
|
Cons(Box::new(newl), Box::new(newr))
|
||||||
|
},
|
||||||
|
_ => return Err(format!("Bad arguments for cons")),
|
||||||
|
},
|
||||||
|
"car" => match operands {
|
||||||
|
Cons(box car, _) => car,
|
||||||
|
_ => return Err(format!("called car with a non-pair argument")),
|
||||||
|
},
|
||||||
|
"cdr" => match operands {
|
||||||
|
Cons(_, box cdr) => cdr,
|
||||||
|
_ => return Err(format!("called cdr with a non-pair argument")),
|
||||||
|
},
|
||||||
|
"atom?" => match operands {
|
||||||
|
Cons(_, _) => False,
|
||||||
|
_ => True,
|
||||||
|
},
|
||||||
|
"define" => match operands {
|
||||||
|
Cons(box SymbolAtom(sym), box Cons(box expr, box Nil)) => {
|
||||||
|
let evaluated = self.eval(expr)?;
|
||||||
|
self.set_var(sym, evaluated);
|
||||||
|
Nil
|
||||||
|
},
|
||||||
|
_ => return Err(format!("Bad assignment")),
|
||||||
|
}
|
||||||
|
"lambda" => match operands {
|
||||||
|
Cons(box paramlist, box Cons(box formalexp, box Nil)) => {
|
||||||
|
unimplemented!() //needs to return an abstract object
|
||||||
|
},
|
||||||
|
_ => return Err(format!("Bad lambda expression")),
|
||||||
|
},
|
||||||
|
"if" => match operands {
|
||||||
|
Cons(box test, box body) => {
|
||||||
|
let truth_value = test.truthy();
|
||||||
|
match (truth_value, body) {
|
||||||
|
(true, Cons(box consequent, _)) => consequent,
|
||||||
|
(false, Cons(_, box Cons(box alternative, _))) => alternative,
|
||||||
|
_ => return Err(format!("Bad if expression"))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => return Err(format!("Bad if expression"))
|
||||||
|
},
|
||||||
|
_ => unimplemented!(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply(&mut self, function: Sexp, operands: Sexp) -> Result<Sexp, String> {
|
||||||
|
Err(format!("Not implemented"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read(input: &str) -> Result<Vec<Sexp>, String> {
|
fn read(input: &str) -> Result<Vec<Sexp>, String> {
|
||||||
|
Loading…
Reference in New Issue
Block a user