Clippy on eval.rs

This commit is contained in:
Greg Shuflin 2021-10-19 21:06:59 -07:00
parent f8c2e57b37
commit c0a3a03045
1 changed files with 26 additions and 28 deletions

View File

@ -14,11 +14,12 @@ pub struct State<'a> {
impl<'a> State<'a> {
pub fn new() -> State<'a> {
let values = ScopeStack::new(Some(format!("global")));
let values = ScopeStack::new(Some("global".to_string()));
State { values }
}
fn new_frame(&'a self, items: &'a Vec<Node>, bound_vars: &BoundVars) -> State<'a> {
#[allow(clippy::ptr_arg)]
fn new_frame(&'a self, items: &'a [Node], bound_vars: &BoundVars) -> State<'a> {
let mut inner_state = State {
values: self.values.new_scope(None),
};
@ -47,7 +48,7 @@ enum Node {
fn paren_wrapped_vec(terms: impl Iterator<Item=String>) -> String {
let mut buf = String::new();
write!(buf, "(").unwrap();
for term in terms.map(|e| Some(e)).intersperse(None) {
for term in terms.map(Some).intersperse(None) {
match term {
Some(e) => write!(buf, "{}", e).unwrap(),
None => write!(buf, ", ").unwrap(),
@ -62,16 +63,13 @@ impl Node {
fn to_repl(&self) -> String {
match self {
Node::Expr(e) => e.to_repl(),
Node::PrimObject { name, items, .. } if items.len() == 0 => format!("{}", name),
Node::PrimObject { name, items, .. } if items.is_empty() => format!("{}", name),
Node::PrimObject { name, items, .. } => format!("{}{}", name, paren_wrapped_vec(items.iter().map(|x| x.to_repl()))),
Node::PrimTuple { items } => format!("{}", paren_wrapped_vec(items.iter().map(|x| x.to_repl()))),
Node::PrimTuple { items } => paren_wrapped_vec(items.iter().map(|x| x.to_repl())),
}
}
fn is_true(&self) -> bool {
match self {
Node::Expr(Expr::Lit(crate::reduced_ast::Lit::Bool(true))) => true,
_ => false,
}
matches!(self, Node::Expr(Expr::Lit(crate::reduced_ast::Lit::Bool(true))))
}
}
@ -86,9 +84,10 @@ enum ValueEntry {
type EvalResult<T> = Result<T, String>;
impl Expr {
fn to_node(self) -> Node {
Node::Expr(self)
}
#[allow(clippy::wrong_self_convention)]
fn to_node(self) -> Node {
Node::Expr(self)
}
fn to_repl(&self) -> String {
use self::Lit::*;
use self::Func::*;
@ -103,7 +102,7 @@ impl Expr {
},
Expr::Func(f) => match f {
BuiltIn(builtin) => format!("<built-in function '{:?}'>", builtin),
UserDefined { name: None, .. } => format!("<function>"),
UserDefined { name: None, .. } => "<function>".to_string(),
UserDefined { name: Some(name), .. } => format!("<function '{}'>", name),
},
Expr::Constructor { type_name, arity, .. } => {
@ -174,7 +173,7 @@ impl<'a> State<'a> {
match stmt {
Stmt::Binding { name, constant, expr } => {
let val = self.expression(Node::Expr(expr))?;
self.values.insert(name.clone(), ValueEntry::Binding { constant, val });
self.values.insert(name, ValueEntry::Binding { constant, val });
Ok(None)
},
Stmt::Expr(expr) => Ok(Some(self.expression(expr.to_node())?)),
@ -214,7 +213,7 @@ impl<'a> State<'a> {
Unit => Ok(Node::Expr(Unit)),
CaseMatch { box cond, alternatives } => self.case_match_expression(cond, alternatives),
ConditionalTargetSigilValue => Ok(Node::Expr(ConditionalTargetSigilValue)),
UnimplementedSigilValue => Err(format!("Sigil value eval not implemented")),
UnimplementedSigilValue => Err("Sigil value eval not implemented".to_string()),
ReductionError(err) => Err(format!("Reduction error: {}", err)),
}
}
@ -237,9 +236,9 @@ impl<'a> State<'a> {
let evaled_args = args.into_iter().map(|expr| self.expression(Node::Expr(expr))).collect::<Result<Vec<Node>,_>>()?;
//let evaled_args = vec![];
Ok(Node::PrimObject {
name: name.clone(),
name,
items: evaled_args,
tag
tag
})
}
@ -286,7 +285,7 @@ impl<'a> State<'a> {
(Multiply, Lit(Nat(l)), Lit(Nat(r))) => Lit(Nat(l * r)),
(Divide, Lit(Nat(l)), Lit(Nat(r))) => Lit(Float((*l as f64)/ (*r as f64))),
(Quotient, Lit(Nat(l)), Lit(Nat(r))) => if *r == 0 {
return Err(format!("divide by zero"));
return Err("Divide-by-zero error".to_string());
} else {
Lit(Nat(l / r))
},
@ -322,8 +321,8 @@ impl<'a> State<'a> {
(prefix, &[Node::Expr(ref arg)]) => match (prefix, arg) {
(BooleanNot, Lit(Bool(true))) => Lit(Bool(false)),
(BooleanNot, Lit(Bool(false))) => Lit(Bool(true)),
(Negate, Lit(Nat(n))) => Lit(Int(-1*(*n as i64))),
(Negate, Lit(Int(n))) => Lit(Int(-1*(*n as i64))),
(Negate, Lit(Nat(n))) => Lit(Int(-(*n as i64))),
(Negate, Lit(Int(n))) => Lit(Int(-(*n as i64))),
(Increment, Lit(Int(n))) => Lit(Int(*n)),
(Increment, Lit(Nat(n))) => Lit(Nat(*n)),
_ => return Err("No valid prefix op".to_string())
@ -352,25 +351,25 @@ impl<'a> State<'a> {
Ok(match cond {
Node::Expr(Expr::Lit(Lit::Bool(true))) => self.block(then_clause)?,
Node::Expr(Expr::Lit(Lit::Bool(false))) => self.block(else_clause)?,
_ => return Err(format!("Conditional with non-boolean condition"))
_ => return Err("Conditional with non-boolean condition".to_string())
})
}
fn assign_expression(&mut self, val: Expr, expr: Expr) -> EvalResult<Node> {
let name = match val {
Expr::Sym(name) => name,
_ => return Err(format!("Trying to assign to a non-value")),
_ => return Err("Trying to assign to a non-value".to_string()),
};
let constant = match self.values.lookup(&name) {
None => return Err(format!("Constant {} is undefined", name)),
Some(ValueEntry::Binding { constant, .. }) => constant.clone(),
Some(ValueEntry::Binding { constant, .. }) => *constant,
};
if constant {
return Err(format!("trying to update {}, a non-mutable binding", name));
}
let val = self.expression(Node::Expr(expr))?;
self.values.insert(name.clone(), ValueEntry::Binding { constant: false, val });
self.values.insert(name, ValueEntry::Binding { constant: false, val });
Ok(Node::Expr(Expr::Unit))
}
@ -390,8 +389,7 @@ impl<'a> State<'a> {
//TODO need to handle recursive subpatterns
let all_subpatterns_pass = |state: &mut State, subpatterns: &Vec<Option<Subpattern>>, items: &Vec<Node>| -> EvalResult<bool> {
if subpatterns.len() == 0 {
if subpatterns.is_empty() {
return Ok(true)
}
@ -401,7 +399,7 @@ impl<'a> State<'a> {
for (maybe_subp, cond) in subpatterns.iter().zip(items.iter()) {
if let Some(subp) = maybe_subp {
if !state.guard_passes(&subp.guard, &cond)? {
if !state.guard_passes(&subp.guard, cond)? {
return Ok(false)
}
}
@ -436,7 +434,7 @@ impl<'a> State<'a> {
}
},
Node::Expr(ref _e) => {
if let None = alt.matchable.tag {
if alt.matchable.tag.is_none() {
return self.block(alt.item)
}
}