Clippy on eval.rs

This commit is contained in:
Greg Shuflin 2021-10-19 21:06:59 -07:00
parent f8c2e57b37
commit c0a3a03045

View File

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