diff --git a/src/parser.rs b/src/parser.rs index 9b92cb9..b064a77 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -65,7 +65,7 @@ pub enum Ast<'src> { Recur(Vec>), } -impl<'src> fmt::Display for Ast<'src> { +impl fmt::Display for Ast<'_> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Ast::Error => write!(f, "Error"), @@ -96,7 +96,7 @@ impl<'src> fmt::Display for Ast<'src> { "#{{{}}}", entries .iter() - .map(|pair| (*pair).0.to_string()) + .map(|pair| pair.0.to_string()) .collect::>() .join(", ") ), @@ -179,13 +179,13 @@ impl<'src> fmt::Display for Ast<'src> { write!(f, "splat: {}", word) } Ast::Pair(k, v) => { - write!(f, "pair: {} {}", k, (*v).0.to_string()) + write!(f, "pair: {} {}", k, v.0) } Ast::Loop(init, body) => { write!( f, "loop: {} with {}", - (*init).0.to_string(), + init.0, body.iter() .map(|clause| clause.to_string()) .collect::>() @@ -235,7 +235,7 @@ pub enum Pattern<'src> { Dict(Vec>), } -impl<'src> fmt::Display for Pattern<'src> { +impl fmt::Display for Pattern<'_> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Pattern::Nil => write!(f, "nil"), @@ -245,7 +245,7 @@ impl<'src> fmt::Display for Pattern<'src> { Pattern::Keyword(k) => write!(f, ":{}", k), Pattern::Word(w) => write!(f, "{}", w), Pattern::As(w, t) => write!(f, "{} as {}", w, t), - Pattern::Splattern(p) => write!(f, "...{}", (*p).0.to_string()), + Pattern::Splattern(p) => write!(f, "...{}", p.0), Pattern::Placeholder => write!(f, "_"), Pattern::Tuple(t) => write!( f, @@ -325,7 +325,7 @@ where ) }); - let splattable = word_pattern.clone().or(placeholder_pattern.clone()); + let splattable = word_pattern.or(placeholder_pattern); let patt_splat = just(Token::Punctuation("...")) .ignore_then(splattable) @@ -430,9 +430,9 @@ where .delimited_by(just(Token::Punctuation("(")), just(Token::Punctuation(")"))) .map_with(|args, e| (Ast::Arguments(args), e.span())); - let synth_root = word.clone().or(keyword.clone()); + let synth_root = word.or(keyword); - let synth_term = keyword.clone().or(args); + let synth_term = keyword.or(args); let synthetic = synth_root .then(synth_term.clone()) @@ -445,7 +445,7 @@ where }); let splat = just(Token::Punctuation("...")) - .ignore_then(word.clone()) + .ignore_then(word) .map_with(|(w, _), e| { ( Ast::Splat(if let Ast::Word(w) = w { @@ -693,7 +693,7 @@ where }); let box_ = just(Token::Reserved("box")) - .ignore_then(word.clone()) + .ignore_then(word) .then_ignore(just(Token::Punctuation("="))) .then(nonbinding.clone()) .map_with(|(word, expr), e| { @@ -706,7 +706,7 @@ where }); let fn_decl = just(Token::Reserved("fn")) - .ignore_then(word.clone()) + .ignore_then(word) .map_with(|(word, _), e| { let name = if let Ast::Word(w) = word { w @@ -717,7 +717,7 @@ where }); let fn_named = just(Token::Reserved("fn")) - .ignore_then(word.clone()) + .ignore_then(word) .then(fn_unguarded.clone()) .map_with(|(word, clause), e| { let name = if let Ast::Word(word) = word.0 { @@ -729,7 +729,7 @@ where }); let fn_compound = just(Token::Reserved("fn")) - .ignore_then(word.clone()) + .ignore_then(word) .then(fn_multiclause.clone()) .map_with(|(word, clauses), e| { let name = if let Ast::Word(word) = word.0 { diff --git a/src/vm.rs b/src/vm.rs index 8c73bae..f2073c7 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -79,13 +79,9 @@ pub fn match_pattern<'src, 'a>( } // todo: add splats to these match clauses (Pattern::Tuple(x), Value::Tuple(y)) => { - let has_splat = x.iter().any(|patt| { - if let (Pattern::Splattern(_), _) = patt { - true - } else { - false - } - }); + let has_splat = x + .iter() + .any(|patt| matches!(patt, (Pattern::Splattern(_), _))); if x.len() > y.len() || (!has_splat && x.len() != y.len()) { return None; }; @@ -97,41 +93,33 @@ pub fn match_pattern<'src, 'a>( list.push_back(y[i].clone()) } let list = Value::List(list); - match_pattern(&(*patt).0, &list, ctx); - } else { - if let None = match_pattern(&x[i].0, &y[i], ctx) { - while ctx.len() > to { - ctx.pop(); - } - return None; + match_pattern(&patt.0, &list, ctx); + } else if match_pattern(&x[i].0, &y[i], ctx).is_none() { + while ctx.len() > to { + ctx.pop(); } + return None; } } Some(ctx) } (Pattern::List(x), Value::List(y)) => { - let has_splat = x.iter().any(|patt| { - if let (Pattern::Splattern(_), _) = patt { - true - } else { - false - } - }); + let has_splat = x + .iter() + .any(|patt| matches!(patt, (Pattern::Splattern(_), _))); if x.len() > y.len() || (!has_splat && x.len() != y.len()) { return None; }; let to = ctx.len(); - for i in 0..x.len() { - if let Pattern::Splattern(patt) = &x[i].0 { + for (i, (patt, _)) in x.iter().enumerate() { + if let Pattern::Splattern(patt) = &patt { let list = Value::List(y.skip(i)); - match_pattern(&(*patt).0, &list, ctx); - } else { - if let None = match_pattern(&x[i].0, &y.get(i).unwrap(), ctx) { - while ctx.len() > to { - ctx.pop(); - } - return None; + match_pattern(&patt.0, &list, ctx); + } else if match_pattern(patt, y.get(i).unwrap(), ctx).is_none() { + while ctx.len() > to { + ctx.pop(); } + return None; } } Some(ctx) @@ -140,28 +128,23 @@ pub fn match_pattern<'src, 'a>( // - [ ] opportunistic mutation // - [ ] get rid of all the pointer indirection in word splats (Pattern::Dict(x), Value::Dict(y)) => { - let has_splat = x.iter().any(|patt| { - if let (Pattern::Splattern(_), _) = patt { - true - } else { - false - } - }); + let has_splat = x + .iter() + .any(|patt| matches!(patt, (Pattern::Splattern(_), _))); if x.len() > y.len() || (!has_splat && x.len() != y.len()) { return None; }; let to = ctx.len(); let mut matched = vec![]; - for i in 0..x.len() { - let (pattern, _) = &x[i]; + for (pattern, _) in x { match pattern { Pattern::Pair(key, patt) => { if let Some(val) = y.get(key) { - if let None = match_pattern(&patt.0, val, ctx) { + if match_pattern(&patt.0, val, ctx).is_none() { while ctx.len() > to { ctx.pop(); - return None; } + return None; } else { matched.push(key); } @@ -169,7 +152,7 @@ pub fn match_pattern<'src, 'a>( return None; }; } - Pattern::Splattern(pattern) => match &(*pattern).0 { + Pattern::Splattern(pattern) => match pattern.0 { Pattern::Word(w) => { // TODO: find a way to take ownership // this will ALWAYS make structural changes, because of this clone @@ -178,7 +161,7 @@ pub fn match_pattern<'src, 'a>( for key in matched.iter() { unmatched.remove(*key); } - ctx.push((*w, Value::Dict(unmatched))); + ctx.push((w, Value::Dict(unmatched))); } Pattern::Placeholder => (), _ => unreachable!(), @@ -192,10 +175,10 @@ pub fn match_pattern<'src, 'a>( } } -pub fn match_clauses<'src, 'a>( +pub fn match_clauses<'src>( value: &Value<'src>, clauses: &'src Vec>, - ctx: &'a mut Vec<(&'src str, Value<'src>)>, + ctx: &mut Vec<(&'src str, Value<'src>)>, ) -> Result, LudusError> { let to = ctx.len(); for MatchClause { patt, body, guard } in clauses.iter() { @@ -203,7 +186,7 @@ pub fn match_clauses<'src, 'a>( let pass_guard = match guard { None => true, Some((ast, _)) => { - let guard_res = eval(&ast, ctx); + let guard_res = eval(ast, ctx); match &guard_res { Err(_) => return guard_res, Ok(val) => val.bool(), @@ -228,10 +211,10 @@ pub fn match_clauses<'src, 'a>( }) } -pub fn apply<'src, 'a>( +pub fn apply<'src>( callee: Value<'src>, caller: Value<'src>, - ctx: &'a mut Vec<(&'src str, Value<'src>)>, + ctx: &mut Vec<(&'src str, Value<'src>)>, ) -> Result, LudusError> { match (callee, caller) { (Value::Keyword(kw), Value::Dict(dict)) => { @@ -368,16 +351,10 @@ pub fn eval<'src, 'a>( Ast::Arguments(a) => { let mut args = vec![]; for (arg, _) in a.iter() { - let arg = eval(&arg, ctx)?; + let arg = eval(arg, ctx)?; args.push(arg); } - if args.iter().any(|arg| { - if let Value::Placeholder = arg { - true - } else { - false - } - }) { + if args.iter().any(|arg| matches!(arg, Value::Placeholder)) { Ok(Value::Args(Rc::new(args))) } else { Ok(Value::Tuple(Rc::new(args))) @@ -429,9 +406,9 @@ pub fn eval<'src, 'a>( return eval(&body.0, ctx); }; } - return Err(LudusError { + Err(LudusError { msg: "no match".to_string(), - }); + }) } Ast::Match(value, clauses) => { let value = eval(&value.0, ctx)?; @@ -468,8 +445,8 @@ pub fn eval<'src, 'a>( } Ast::Do(terms) => { let mut result = eval(&terms[0].0, ctx)?; - for i in 1..terms.len() { - let next = eval(&terms[i].0, ctx)?; + for (term, _) in terms.iter().skip(1) { + let next = eval(term, ctx)?; let arg = Value::Tuple(Rc::new(vec![result])); result = apply(next, arg, ctx)?; }