Skip to main content

ScopeMap

Struct ScopeMap 

Source
pub struct ScopeMap<V> { /* private fields */ }
Expand description

A map from a name to a value, in a stack of scopes.

A lookup has to find the innermost binding of a name, and a scope closing has to expose whatever that name meant outside it. Walking a stack of scopes would make every lookup cost the depth, and a compiler looks up every identifier it reads, so the shape is inverted: one map from name to the stack of bindings for that name, innermost last, plus a log of the names bound in each open scope so that closing one knows what to undo.

Implementations§

Source§

impl<V: Copy> ScopeMap<V>

Source

pub fn new() -> Self

An empty namespace, with the file scope open.

Source

pub fn depth(&self) -> u32

How many scopes are open. The file scope counts, so this is never zero.

Source

pub fn at_file_scope(&self) -> bool

Whether the only open scope is the file scope.

Source

pub fn push(&mut self)

Opens a scope.

Source

pub fn pop(&mut self)

Closes the innermost scope, exposing whatever its names meant outside it.

§Panics

Panics on closing the file scope, which nothing in C does and which would leave the namespace unable to hold a declaration.

Source

pub fn declare(&mut self, name: Symbol, value: V) -> Option<V>

Binds name in the innermost scope, and gives back what it was already bound to in that same scope.

A returned value is a redeclaration, which is the caller’s to judge: int x; int x; is fine at file scope and typedef int T; T T; is not, and neither decision belongs here. Shadowing an outer binding is not a redeclaration and gives back None.

Source

pub fn declare_at_file_scope(&mut self, name: Symbol, value: V) -> bool

Binds name in the file scope from wherever the caller is, and answers whether it took.

For the declaration a program did not write. A builtin used inside a function is declared where C says the implementation declared it, which is the file scope, so that what it means does not change when the block it was first used in closes.

It takes only when the name is bound nowhere, which is the caller’s own condition: this is reached because a lookup found nothing. A name bound anywhere is left alone rather than bound underneath, because the binding it already has may be the one being closed over and this has no log entry to undo.

Source

pub fn get(&self, name: Symbol) -> Option<V>

What name is bound to in the innermost scope that binds it.

Source

pub fn get_here(&self, name: Symbol) -> Option<V>

What name is bound to in the innermost scope alone, ignoring the ones outside it.

Trait Implementations§

Source§

impl<V: Debug> Debug for ScopeMap<V>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<V> Default for ScopeMap<V>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<V> Freeze for ScopeMap<V>
where HashMap<Symbol, Vec<Binding<V>>>: Freeze,

§

impl<V> RefUnwindSafe for ScopeMap<V>
where HashMap<Symbol, Vec<Binding<V>>>: RefUnwindSafe,

§

impl<V> Send for ScopeMap<V>
where HashMap<Symbol, Vec<Binding<V>>>: Send,

§

impl<V> Sync for ScopeMap<V>
where HashMap<Symbol, Vec<Binding<V>>>: Sync,

§

impl<V> Unpin for ScopeMap<V>
where HashMap<Symbol, Vec<Binding<V>>>: Unpin,

§

impl<V> UnsafeUnpin for ScopeMap<V>
where HashMap<Symbol, Vec<Binding<V>>>: UnsafeUnpin,

§

impl<V> UnwindSafe for ScopeMap<V>
where HashMap<Symbol, Vec<Binding<V>>>: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.