Stuff and bother.

This commit is contained in:
2025-11-24 18:31:44 -08:00
parent 90c5d6fef8
commit 2ef9ae8bdc
11 changed files with 1403 additions and 236 deletions

View File

@@ -1,12 +1,14 @@
use crate::syntax::Location;
#[cfg(test)]
use internment::ArcIntern;
use std::cmp;
use std::fmt;
use std::hash;
use std::hash::{Hash, Hasher};
use std::sync::atomic::{AtomicU64, Ordering};
static IDENTIFIER_COUNTER: AtomicU64 = AtomicU64::new(0);
#[derive(Debug)]
#[derive(Clone, Debug)]
pub struct Name {
printable: String,
identifier: u64,
@@ -21,8 +23,8 @@ impl cmp::PartialEq for Name {
impl cmp::Eq for Name {}
impl hash::Hash for Name {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
impl Hash for Name {
fn hash<H: Hasher>(&self, state: &mut H) {
self.identifier.hash(state);
}
}
@@ -66,3 +68,89 @@ impl Name {
self.location.as_ref()
}
}
#[test]
fn equality() {
let file = ArcIntern::new("/foo.bang".into());
let loc1 = Location::new(&file, 0..3);
let loc2 = Location::new(&file, 9..12);
assert_ne!(Name::gensym("x"), Name::gensym("x"));
assert_ne!(Name::new(loc1.clone(), "x"), Name::new(loc1.clone(), "x"));
assert_eq!(
Name {
printable: "x".into(),
identifier: 5,
location: Some(loc1.clone())
},
Name {
printable: "x".into(),
identifier: 5,
location: Some(loc2.clone())
}
);
assert_eq!(
Name {
printable: "x".into(),
identifier: 5,
location: Some(loc1.clone())
},
Name {
printable: "x".into(),
identifier: 5,
location: None
}
);
assert_eq!(
Name {
printable: "x".into(),
identifier: 5,
location: Some(loc1.clone())
},
Name {
printable: "y".into(),
identifier: 5,
location: None
}
);
}
#[test]
fn hashing() {
let file = ArcIntern::new("/foo.bang".into());
let loc1 = Location::new(&file, 0..3);
let loc2 = Location::new(&file, 9..12);
let x1 = Name {
printable: "x".into(),
identifier: 1,
location: Some(loc1),
};
let mut x2 = Name {
printable: "x".into(),
identifier: 2,
location: Some(loc2),
};
let y1 = Name {
printable: "y".into(),
identifier: 1,
location: None,
};
let run_hash = |name: &Name| {
let mut hash = std::hash::DefaultHasher::new();
name.hash(&mut hash);
hash.finish()
};
let hash_x1 = run_hash(&x1);
let hash_x2 = run_hash(&x2);
let hash_y1 = run_hash(&y1);
assert_ne!(hash_x1, hash_x2);
assert_eq!(hash_x1, hash_y1);
x2.bind_to(&x1);
let rehashed_x2 = run_hash(&x2);
assert_eq!(hash_x1, rehashed_x2);
}