fix match bug

i hope so. put equality checking after variable checking when matching symbols
This commit is contained in:
mehbark 2023-06-15 00:43:56 -04:00
parent 17463c839f
commit c7354d3c56

View file

@ -506,12 +506,12 @@ type Matches<'src> = HashMap<Symbol, &'src Sexp>;
pub fn matches<'src>(vars: &[Symbol], lhs: &Sexp, expr: &'src Sexp) -> Option<Matches<'src>> { pub fn matches<'src>(vars: &[Symbol], lhs: &Sexp, expr: &'src Sexp) -> Option<Matches<'src>> {
match (lhs, expr) { match (lhs, expr) {
(Sexp::Atom(a), Sexp::Atom(b)) => { (Sexp::Atom(a), Sexp::Atom(b)) => {
if a == b { if vars.contains(a) {
Some(HashMap::with_capacity(0))
} else if vars.contains(a) {
let mut out = HashMap::with_capacity(1); let mut out = HashMap::with_capacity(1);
out.insert(*a, expr); out.insert(*a, expr);
Some(out) Some(out)
} else if a == b {
Some(HashMap::with_capacity(0))
} else { } else {
None None
} }
@ -527,7 +527,7 @@ pub fn matches<'src>(vars: &[Symbol], lhs: &Sexp, expr: &'src Sexp) -> Option<Ma
} }
(Sexp::List(_), Sexp::Atom(_)) => None, (Sexp::List(_), Sexp::Atom(_)) => None,
(Sexp::List(xs), Sexp::List(ys)) => { (Sexp::List(xs), Sexp::List(ys)) => {
if xs == ys { if xs.is_empty() && ys.is_empty() {
Some(HashMap::with_capacity(0)) Some(HashMap::with_capacity(0))
} else if xs.len() == ys.len() { } else if xs.len() == ys.len() {
xs.iter() xs.iter()
@ -535,7 +535,7 @@ pub fn matches<'src>(vars: &[Symbol], lhs: &Sexp, expr: &'src Sexp) -> Option<Ma
.map(|(lhs, expr)| matches(vars, lhs, expr)) .map(|(lhs, expr)| matches(vars, lhs, expr))
.reduce(|a, b| match (a, b) { .reduce(|a, b| match (a, b) {
(None, _) | (_, None) => None, (None, _) | (_, None) => None,
(Some(a), Some(b)) => merge_matches(vars, a, b), (Some(a), Some(b)) => merge_matches(vars, &a, &b),
}) })
.unwrap_or(None) .unwrap_or(None)
} else { } else {
@ -545,10 +545,11 @@ pub fn matches<'src>(vars: &[Symbol], lhs: &Sexp, expr: &'src Sexp) -> Option<Ma
} }
} }
#[must_use]
pub fn merge_matches<'src>( pub fn merge_matches<'src>(
vars: &[Symbol], vars: &[Symbol],
a: Matches<'src>, a: &Matches<'src>,
b: Matches<'src>, b: &Matches<'src>,
) -> Option<Matches<'src>> { ) -> Option<Matches<'src>> {
let mut out = HashMap::with_capacity(vars.len()); let mut out = HashMap::with_capacity(vars.len());
@ -579,6 +580,7 @@ pub fn merge_matches<'src>(
// } // }
// } // }
#[must_use]
pub fn rw(rule: &Rule, sexp: &Sexp) -> Sexp { pub fn rw(rule: &Rule, sexp: &Sexp) -> Sexp {
if rule.lhs() == rule.rhs() { if rule.lhs() == rule.rhs() {
return sexp.clone(); return sexp.clone();