diff --git a/schala-lang/language/src/eval/mod.rs b/schala-lang/language/src/eval/mod.rs index fb8912f..8f238da 100644 --- a/schala-lang/language/src/eval/mod.rs +++ b/schala-lang/language/src/eval/mod.rs @@ -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, 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) -> 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 = Result; 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!("", builtin), - UserDefined { name: None, .. } => format!(""), + UserDefined { name: None, .. } => "".to_string(), UserDefined { name: Some(name), .. } => format!("", 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::,_>>()?; //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 { 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>, items: &Vec| -> EvalResult { - - 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) } }