tamer: Symbol{Index=>Id}

The former was a misnomer (it represents an index _entry_).  This name is
also shorter, which is nice, considering how often it'll be used.
main
Mike Gerwitz 2021-07-30 13:31:59 -04:00
parent 0fc8a1a4df
commit 01722c9c3b
6 changed files with 70 additions and 71 deletions

View File

@ -40,7 +40,7 @@ use petgraph::visit::DfsPostOrder;
/// This implementation is currently based on [`petgraph`].
///
/// Identifiers are cached by name for `O(1)` lookup.
/// Since [`SymbolIndex`][crate::sym::SymbolIndex] is used for this purpose,
/// Since [`SymbolId`][crate::sym::SymbolId] is used for this purpose,
/// the index may contain more entries than nodes and may contain gaps.
///
/// For more information,
@ -52,7 +52,7 @@ where
/// Directed graph on which objects are stored.
graph: DiGraph<Node<O>, AsgEdge, Ix>,
/// Map of [`SymbolIndex`][crate::sym::SymbolIndex] to node indexes.
/// Map of [`SymbolId`][crate::sym::SymbolId] to node indexes.
///
/// This allows for `O(1)` lookup of identifiers in the graph.
/// Note that,
@ -406,7 +406,7 @@ mod test {
UnresolvedError,
};
use crate::ir::legacyir::SymDtype;
use crate::sym::SymbolIndex;
use crate::sym::SymbolId;
use std::cell::RefCell;
type Ix = u8;

View File

@ -729,7 +729,7 @@ where
mod test {
use super::super::ident::Dim;
use super::*;
use crate::sym::SymbolIndex;
use crate::sym::SymbolId;
mod ident_object_data {
use super::*;

View File

@ -154,7 +154,7 @@ impl<'a, T> Sections<'a, T> {
mod test {
use super::*;
use crate::ir::asg::IdentObject;
use crate::sym::{Symbol, SymbolIndex};
use crate::sym::{Symbol, SymbolId};
lazy_static! {
static ref SYM: Symbol<'static, u16> = symbol_dummy!(1, "sym");

View File

@ -73,7 +73,7 @@ impl<W: Write> XmleWriter<W> {
/// use std::io::Cursor;
/// use tamer::obj::xmle::writer::XmleWriter;
/// use tamer::ir::asg::{Sections, IdentObject};
/// use tamer::sym::{Symbol, SymbolIndex, DefaultProgInterner, Interner};
/// use tamer::sym::{Symbol, SymbolId, DefaultProgInterner, Interner};
///
/// let writer = Cursor::new(Vec::new());
/// let mut xmle_writer = XmleWriter::new(writer);
@ -422,7 +422,7 @@ mod test {
use super::*;
use crate::ir::asg::{Dim, Section, Source};
use crate::ir::legacyir::SymAttrs;
use crate::sym::{Symbol, SymbolIndex};
use crate::sym::{Symbol, SymbolId};
use std::str;
type Sut<W> = XmleWriter<W>;

View File

@ -359,7 +359,7 @@ mod test {
use super::*;
use crate::ir::asg::{DefaultAsg, FragmentText, IdentObject};
use crate::ir::legacyir::{PackageAttrs, SymAttrs, SymType};
use crate::sym::SymbolIndex;
use crate::sym::SymbolId;
use std::collections::hash_map::RandomState;
type SutIx = u8;

View File

@ -35,7 +35,7 @@
//! [arena]: bumpalo
//!
//! ```
//! use tamer::sym::{Interner, DefaultInterner, Symbol, SymbolIndex};
//! use tamer::sym::{Interner, DefaultInterner, Symbol, SymbolId};
//!
//! // Inputs to be interned
//! let a = "foo";
@ -70,10 +70,10 @@
//!
//! // Each symbol has an associated, densely-packed integer value
//! // that can be used for indexing
//! assert_eq!(SymbolIndex::from_int(1u16), ia.index());
//! assert_eq!(SymbolIndex::from_int(1u16), ib.index());
//! assert_eq!(SymbolIndex::from_int(2u16), ic.index());
//! assert_eq!(SymbolIndex::from_int(1u16), id.index());
//! assert_eq!(SymbolId::from_int(1u16), ia.index());
//! assert_eq!(SymbolId::from_int(1u16), ib.index());
//! assert_eq!(SymbolId::from_int(2u16), ic.index());
//! assert_eq!(SymbolId::from_int(1u16), id.index());
//!
//! // Symbols can also be looked up by index.
//! assert_eq!(Some(ia), interner.index_lookup(ia.index()));
@ -129,7 +129,7 @@
//! (see [`Symbol::index`]),
//! which provides a dense range of values suitable for use in vectors
//! as an alternative to [`HashMap`] for mapping symbol data.
//! A [`SymbolIndex`] can be mapped back into its associated [`Symbol`]
//! A [`SymbolId`] can be mapped back into its associated [`Symbol`]
//! using [`Interner::index_lookup`].
//!
//! Since a reference to the same [`Symbol`] is returned for each
@ -150,7 +150,7 @@
//! - Retrieves symbol values by pointer reference without requiring use
//! of [`Interner`] or a locking mechanism; and
//! - Stores [`Symbol`] objects in the arena rather than within a vector
//! indexed by [`SymbolIndex`].
//! indexed by [`SymbolId`].
//!
//!
//! Name Mangling
@ -289,29 +289,29 @@ use std::{fmt, fmt::Debug};
///
/// The index `0` is never valid because of
/// [`SymbolIndexSize::NonZero`],
/// which allows us to have `Option<SymbolIndex>` at no space cost.
/// which allows us to have `Option<SymbolId>` at no space cost.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct SymbolIndex<Ix: SymbolIndexSize>(Ix::NonZero);
pub struct SymbolId<Ix: SymbolIndexSize>(Ix::NonZero);
assert_eq_size!(Option<Symbol<u16>>, Symbol<u16>);
impl<Ix: SymbolIndexSize> SymbolIndex<Ix> {
impl<Ix: SymbolIndexSize> SymbolId<Ix> {
/// Construct index from a non-zero `u16` value.
///
/// Panics
/// ------
/// Will panic if `n == 0`.
pub fn from_int(n: Ix) -> SymbolIndex<Ix> {
SymbolIndex(Ix::new(n).unwrap())
pub fn from_int(n: Ix) -> SymbolId<Ix> {
SymbolId(Ix::new(n).unwrap())
}
/// Construct index from an unchecked non-zero `u16` value.
///
/// This does not verify that `n > 0` and so must only be used in
/// contexts where this invariant is guaranteed to hold.
/// Unlike [`from_int`](SymbolIndex::from_int),
/// Unlike [`from_int`](SymbolId::from_int),
/// this never panics.
unsafe fn from_int_unchecked(n: Ix) -> SymbolIndex<Ix> {
SymbolIndex(Ix::new_unchecked(n))
unsafe fn from_int_unchecked(n: Ix) -> SymbolId<Ix> {
SymbolId(Ix::new_unchecked(n))
}
/// Construct index from a non-zero `u16` value.
@ -319,8 +319,8 @@ impl<Ix: SymbolIndexSize> SymbolIndex<Ix> {
/// Panics
/// ------
/// Will panic if `n == 0`.
pub fn from_u16(n: u16) -> SymbolIndex<u16> {
SymbolIndex::from_int(n)
pub fn from_u16(n: u16) -> SymbolId<u16> {
SymbolId::from_int(n)
}
/// Construct index from a non-zero `u32` value.
@ -328,21 +328,21 @@ impl<Ix: SymbolIndexSize> SymbolIndex<Ix> {
/// Panics
/// ------
/// Will panic if `n == 0`.
pub fn from_u32(n: u32) -> SymbolIndex<u32> {
SymbolIndex::from_int(n)
pub fn from_u32(n: u32) -> SymbolId<u32> {
SymbolId::from_int(n)
}
}
impl<Ix: SymbolIndexSize> From<SymbolIndex<Ix>> for usize
impl<Ix: SymbolIndexSize> From<SymbolId<Ix>> for usize
where
<Ix as TryInto<usize>>::Error: Debug,
{
fn from(value: SymbolIndex<Ix>) -> usize {
fn from(value: SymbolId<Ix>) -> usize {
value.0.into().into_usize()
}
}
impl<'i, Ix: SymbolIndexSize> From<&Symbol<'i, Ix>> for SymbolIndex<Ix> {
impl<'i, Ix: SymbolIndexSize> From<&Symbol<'i, Ix>> for SymbolId<Ix> {
fn from(sym: &Symbol<'i, Ix>) -> Self {
sym.index()
}
@ -370,7 +370,7 @@ pub trait SymbolIndexSize:
/// A symbol with a static lifetime suitable for placement at index 0 in
/// the string interment table,
/// which is not a valid [`SymbolIndex`] value.
/// which is not a valid [`SymbolId`] value.
fn dummy_sym() -> &'static Symbol<'static, Self>;
/// Construct a new non-zero value from the provided primitive value.
@ -431,7 +431,7 @@ supported_symbol_index!(u32, NonZeroU32, DUMMY_SYM_32);
/// this is especially beneficial for portions of the system that make
/// use of nearly all interned symbols,
/// like the ASG.
/// A [`SymbolIndex`] can be mapped back into its [`Symbol`] by calling
/// A [`SymbolId`] can be mapped back into its [`Symbol`] by calling
/// [`Interner::index_lookup`] on the same interner that produced it.
///
/// The symbol also stores a string slice referencing the interned string
@ -440,7 +440,7 @@ supported_symbol_index!(u32, NonZeroU32, DUMMY_SYM_32);
/// Dereferencing the symbol will expose the underlying slice.
#[derive(Copy, Clone, Debug)]
pub struct Symbol<'i, Ix: SymbolIndexSize> {
index: SymbolIndex<Ix>,
index: SymbolId<Ix>,
str: &'i str,
}
@ -467,7 +467,7 @@ impl<'i, Ix: SymbolIndexSize> Symbol<'i, Ix> {
/// For test builds (when `cfg(test)`),
/// `new_dummy` is available to create symbols for tests.
#[inline]
fn new(index: SymbolIndex<Ix>, str: &'i str) -> Symbol<'i, Ix> {
fn new(index: SymbolId<Ix>, str: &'i str) -> Symbol<'i, Ix> {
Self { index, str }
}
@ -475,9 +475,9 @@ impl<'i, Ix: SymbolIndexSize> Symbol<'i, Ix> {
///
/// This is a densely-packed identifier that can be used as an index for
/// mapping.
/// See [`SymbolIndex`] for more information.
/// See [`SymbolId`] for more information.
#[inline]
pub fn index(&self) -> SymbolIndex<Ix> {
pub fn index(&self) -> SymbolId<Ix> {
self.index
}
@ -491,7 +491,7 @@ impl<'i, Ix: SymbolIndexSize> Symbol<'i, Ix> {
/// See also `dummy_symbol!`.
#[cfg(test)]
#[inline(always)]
pub fn new_dummy(index: SymbolIndex<Ix>, str: &'i str) -> Symbol<'i, Ix> {
pub fn new_dummy(index: SymbolId<Ix>, str: &'i str) -> Symbol<'i, Ix> {
Self::new(index, str)
}
}
@ -532,28 +532,28 @@ lazy_static! {
///
/// A symbol must never have an index of `0`,
/// so this can be used as a placeholder.
/// The chosen [`SymbolIndex`] here does not matter since this will
/// The chosen [`SymbolId`] here does not matter since this will
/// never be referenced.
static ref DUMMY_SYM_8: Symbol<'static, u8> =
Symbol::new(SymbolIndex::from_int(1), "!BADSYMREF!");
Symbol::new(SymbolId::from_int(1), "!BADSYMREF!");
/// Dummy 16-bit [`Symbol`] for use at index `0`.
///
/// A symbol must never have an index of `0`,
/// so this can be used as a placeholder.
/// The chosen [`SymbolIndex`] here does not matter since this will
/// The chosen [`SymbolId`] here does not matter since this will
/// never be referenced.
static ref DUMMY_SYM_16: Symbol<'static, u16> =
Symbol::new(SymbolIndex::from_int(1), "!BADSYMREF!");
Symbol::new(SymbolId::from_int(1), "!BADSYMREF!");
/// Dummy 32-bit [`Symbol`] for use at index `0`.
///
/// A symbol must never have an index of `0`,
/// so this can be used as a placeholder.
/// The chosen [`SymbolIndex`] here does not matter since this will
/// The chosen [`SymbolId`] here does not matter since this will
/// never be referenced.
static ref DUMMY_SYM_32: Symbol<'static, u32> =
Symbol::new(SymbolIndex::from_int(1), "!BADSYMREF!");
Symbol::new(SymbolId::from_int(1), "!BADSYMREF!");
}
/// Create, store, compare, and retrieve [`Symbol`] values.
@ -601,7 +601,7 @@ pub trait Interner<'i, Ix: SymbolIndexSize> {
/// It does not increase when a string is already interned.
fn len(&self) -> usize;
/// Look up a previously interned [`Symbol`] by its [`SymbolIndex`].
/// Look up a previously interned [`Symbol`] by its [`SymbolId`].
///
/// This will always return a [`Symbol`] as long as the provided `index`
/// represents a symbol interned with this interner.
@ -612,11 +612,11 @@ pub trait Interner<'i, Ix: SymbolIndexSize> {
/// or desirable.
/// For example,
/// borrowed [`Symbol`] references require lifetimes,
/// whereas [`SymbolIndex`] is both owned _and_ [`Copy`].
/// [`SymbolIndex`] is also much smaller than [`Symbol`].
/// whereas [`SymbolId`] is both owned _and_ [`Copy`].
/// [`SymbolId`] is also much smaller than [`Symbol`].
fn index_lookup(
&'i self,
index: SymbolIndex<Ix>,
index: SymbolId<Ix>,
) -> Option<&'i Symbol<'i, Ix>>;
/// Intern an assumed-UTF8 slice of bytes or return an existing
@ -662,10 +662,10 @@ where
/// Symbol references by index.
///
/// This vector enables looking up a [`Symbol`] using its
/// [`SymbolIndex`].
/// [`SymbolId`].
///
/// The first index must always be populated during initialization to
/// ensure that [`SymbolIndex`] will never be `0`.
/// ensure that [`SymbolId`] will never be `0`.
indexes: RefCell<Vec<&'i Symbol<'i, Ix>>>,
/// Map of interned strings to their respective [`Symbol`].
@ -706,7 +706,7 @@ where
pub fn with_capacity(capacity: usize) -> Self {
let mut indexes = Vec::<&'i Symbol<'i, Ix>>::with_capacity(capacity);
// The first index is not used since SymbolIndex cannot be 0.
// The first index is not used since SymbolId cannot be 0.
indexes.push(Ix::dummy_sym());
Self {
@ -738,12 +738,12 @@ where
let next_index: Ix = syms
.len()
.try_into()
.expect("internal error: SymbolIndex range exhausted");
.expect("internal error: SymbolId range exhausted");
// This is not actually unsafe because next_index is always >0
// from initialization.
debug_assert!(Ix::new(next_index).is_some()); // != 0 check
let id = unsafe { SymbolIndex::from_int_unchecked(next_index) };
let id = unsafe { SymbolId::from_int_unchecked(next_index) };
// Copy string slice into the arena.
let clone: &'i str = unsafe {
@ -779,7 +779,7 @@ where
fn index_lookup(
&'i self,
index: SymbolIndex<Ix>,
index: SymbolId<Ix>,
) -> Option<&'i Symbol<'i, Ix>> {
self.indexes
.borrow()
@ -829,7 +829,7 @@ pub type DefaultProgInterner<'i> = DefaultInterner<'i, global::ProgSymSize>;
#[cfg(test)]
macro_rules! symbol_dummy {
($id:expr, $name:expr) => {
Symbol::new_dummy(SymbolIndex::from_int($id), $name);
Symbol::new_dummy(SymbolId::from_int($id), $name);
};
}
@ -842,14 +842,14 @@ mod test {
#[test]
fn self_compares_eq() {
let sym = Symbol::new(SymbolIndex::from_int(1u16), "str");
let sym = Symbol::new(SymbolId::from_int(1u16), "str");
assert_eq!(&sym, &sym);
}
#[test]
fn copy_compares_equal() {
let sym = Symbol::new(SymbolIndex::from_int(1u16), "str");
let sym = Symbol::new(SymbolId::from_int(1u16), "str");
let cpy = sym;
assert_eq!(sym, cpy);
@ -859,8 +859,8 @@ mod test {
// used as a unique identifier across different interners.
#[test]
fn same_index_different_slices_compare_unequal() {
let a = Symbol::new(SymbolIndex::from_int(1u16), "a");
let b = Symbol::new(SymbolIndex::from_int(1u16), "b");
let a = Symbol::new(SymbolId::from_int(1u16), "a");
let b = Symbol::new(SymbolId::from_int(1u16), "b");
assert_ne!(a, b);
}
@ -876,15 +876,15 @@ mod test {
fn different_index_same_slices_compare_equal() {
let slice = "str";
let a = Symbol::new(SymbolIndex::from_int(1u16), slice);
let b = Symbol::new(SymbolIndex::from_int(2u16), slice);
let a = Symbol::new(SymbolId::from_int(1u16), slice);
let b = Symbol::new(SymbolId::from_int(2u16), slice);
assert_eq!(a, b);
}
#[test]
fn cloned_symbols_compare_equal() {
let sym = Symbol::new(SymbolIndex::from_int(1u16), "foo");
let sym = Symbol::new(SymbolId::from_int(1u16), "foo");
assert_eq!(sym, sym.clone());
}
@ -894,8 +894,7 @@ mod test {
#[test]
fn ref_can_be_used_as_string_slice() {
let slice = "str";
let sym_slice: &str =
&Symbol::new(SymbolIndex::from_int(1u16), slice);
let sym_slice: &str = &Symbol::new(SymbolId::from_int(1u16), slice);
assert_eq!(slice, sym_slice);
}
@ -903,21 +902,21 @@ mod test {
// For use when we can guarantee proper ids.
#[test]
fn can_create_index_unchecked() {
assert_eq!(SymbolIndex::from_int(1u32), unsafe {
SymbolIndex::from_int_unchecked(1)
assert_eq!(SymbolId::from_int(1u32), unsafe {
SymbolId::from_int_unchecked(1)
});
}
#[test]
fn can_retrieve_symbol_index() {
let index = SymbolIndex::from_int(1u16);
let index = SymbolId::from_int(1u16);
assert_eq!(index, Symbol::new(index, "").index());
}
#[test]
fn displays_as_interned_value() {
let sym = Symbol::new(SymbolIndex::from_int(1u16), "foo");
let sym = Symbol::new(SymbolId::from_int(1u16), "foo");
assert_eq!(format!("{}", sym), sym.str);
}
@ -959,19 +958,19 @@ mod test {
// Remember that identifiers begin at 1
assert_eq!(
SymbolIndex::from_int(1),
SymbolId::from_int(1),
sut.intern("foo").index(),
"First index should be 1"
);
assert_eq!(
SymbolIndex::from_int(1),
SymbolId::from_int(1),
sut.intern("foo").index(),
"Index should not increment for already-interned symbols"
);
assert_eq!(
SymbolIndex::from_int(2),
SymbolId::from_int(2),
sut.intern("bar").index(),
"Index should increment for new symbols"
);
@ -1037,7 +1036,7 @@ mod test {
let sut = Sut::new();
// Symbol does not yet exist.
assert!(sut.index_lookup(SymbolIndex::from_int(1)).is_none());
assert!(sut.index_lookup(SymbolId::from_int(1)).is_none());
let sym = sut.intern("foo");
assert_eq!(Some(sym), sut.index_lookup(sym.index()));