tamer: ir::asg::ident: AsRef impls for SymbolId types

This commit will make more sense once the broader context is committed, but
it's needed for lowering from `Sections` into a XIR stream.

This will also change once we pre-allocate symbols, like rustc, when the
interner is initialized.

This is my first use of the `paste` crate, which is used to generate
identifiers.  So this is partly an experiment, and it seems much better than
having to write a proc macro, at least at this point in time.  If this code
stays around, it'll probably be generalized further and used elsewhere, but
I'd prefer not to go this route long-term.
main
Mike Gerwitz 2021-09-20 16:46:16 -04:00
parent 12daddcc2d
commit 3bb6f0cf35
4 changed files with 77 additions and 25 deletions

7
tamer/Cargo.lock generated
View File

@ -145,6 +145,12 @@ dependencies = [
"autocfg",
]
[[package]]
name = "paste"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58"
[[package]]
name = "petgraph"
version = "0.5.1"
@ -303,6 +309,7 @@ dependencies = [
"getopts",
"lazy_static",
"memchr",
"paste",
"petgraph",
"petgraph-graphml",
"predicates",

View File

@ -37,6 +37,7 @@ lazy_static = ">= 1.4.0"
petgraph-graphml = ">= 2.0.1"
static_assertions = ">= 1.1.0"
memchr = ">= 2.3.4" # quick-xml expects =2.3.4 at the time
paste = ">= 1.0.5"
# Feature flags can be specified using `./configure FEATURES=foo,bar,baz`.
#

View File

@ -19,8 +19,10 @@
//! Identifiers (a type of [object][super::object::IdentObject]).
use crate::global;
use crate::ir::legacyir::{SymAttrs, SymDtype, SymType};
use crate::sym::SymbolIndexSize;
use crate::sym::{GlobalSymbolIntern, SymbolId, SymbolIndexSize};
use paste::paste;
use std::convert::TryFrom;
use std::error::Error;
@ -146,31 +148,75 @@ pub enum IdentKind {
Worksheet,
}
impl AsRef<str> for IdentKind {
fn as_ref(&self) -> &'static str {
match self {
Self::Cgen(_) => "cgen",
Self::Class(_) => "class",
Self::Const(_, _) => "const",
Self::Func(_, _) => "func",
Self::Gen(_, _) => "gen",
Self::Lparam(_, _) => "lparam",
Self::Param(_, _) => "param",
Self::Rate(_) => "rate",
Self::Tpl => "tpl",
Self::Type(_) => "type",
Self::MapHead => "map:head",
Self::Map => "map",
Self::MapTail => "map:tail",
Self::RetMapHead => "retmap:head",
Self::RetMap => "retmap",
Self::RetMapTail => "retmap:tail",
Self::Meta => "meta",
Self::Worksheet => "worksheet",
/// Produce [`AsRef`] impls for [`str`], [`global::ProgSymSize`] and
/// [`global::PkgSymSize`] for identifier kind strings.
macro_rules! kind_intern {
($($variant:ident $($v:pat)? => $str:expr),*) => {
paste! {
lazy_static! {
$(
static ref [<PROG_KIND_ $variant:upper>]: SymbolId<global::ProgSymSize>
= $str.intern();
static ref [<PKG_KIND_ $variant:upper>]: SymbolId<global::PkgSymSize>
= $str.intern();
)*
}
impl AsRef<str> for IdentKind {
fn as_ref(&self) -> &'static str {
match self {
$(
Self::$variant$($v)* => $str,
)*
}
}
}
impl AsRef<SymbolId<global::ProgSymSize>> for IdentKind {
fn as_ref(&self) -> &SymbolId<global::ProgSymSize> {
match self {
$(
Self::$variant$($v)* => &[<PROG_KIND_ $variant:upper>],
)*
}
}
}
impl AsRef<SymbolId<global::PkgSymSize>> for IdentKind {
fn as_ref(&self) -> &SymbolId<global::PkgSymSize> {
match self {
$(
Self::$variant$($v)* => &[<PKG_KIND_ $variant:upper>],
)*
}
}
}
}
}
}
// In the future, we'll pre-populate the internment pool, like rustc.
kind_intern! {
Cgen(_) => "cgen",
Class(_) => "class",
Const(_, _) => "const",
Func(_, _) => "func",
Gen(_, _) => "gen",
Lparam(_, _) => "lparam",
Param(_, _) => "param",
Rate(_) => "rate",
Tpl => "tpl",
Type(_) => "type",
MapHead => "map:head",
Map => "map",
MapTail => "map:tail",
RetMapHead => "retmap:head",
RetMap => "retmap",
RetMapTail => "retmap:tail",
Meta => "meta",
Worksheet => "worksheet"
}
impl std::fmt::Display for IdentKind {
/// Format identifier type for display to the user.
///
@ -178,7 +224,7 @@ impl std::fmt::Display for IdentKind {
/// new type system,
/// so for now this just uses a syntax similar to Rust.
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
let name = self.as_ref();
let name: &str = self.as_ref();
match self {
Self::Cgen(dim) => {

View File

@ -26,8 +26,6 @@ pub mod global;
#[macro_use]
extern crate static_assertions;
#[cfg(test)]
#[macro_use]
extern crate lazy_static;