tamer: ir::asg::ident: Use symbols in place of string slice mapping

`IdentKind` needs to be written to `xmle` files and displayed in error
messages.  String slices were used when quick-xml was used for writing,
which will be going away with the new writer.
main
Mike Gerwitz 2021-09-29 23:18:23 -04:00
parent fa4181770f
commit 5250571f15
5 changed files with 56 additions and 61 deletions

View File

@ -20,8 +20,7 @@
//! Identifiers (a type of [object][super::object::IdentObject]). //! Identifiers (a type of [object][super::object::IdentObject]).
use crate::ir::legacyir::{SymAttrs, SymDtype, SymType}; use crate::ir::legacyir::{SymAttrs, SymDtype, SymType};
use crate::sym::{GlobalSymbolIntern, SymbolId}; use crate::sym::{st, GlobalSymbolResolve, SymbolId};
use paste::paste;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::error::Error; use std::error::Error;
@ -147,63 +146,31 @@ pub enum IdentKind {
Worksheet, Worksheet,
} }
/// Produce [`AsRef`] impls for [`str`] and [`global::ProgSymSize`] for impl IdentKind {
/// identifier kind strings. pub fn as_sym(&self) -> SymbolId {
macro_rules! kind_intern { match self {
($($variant:ident $($v:pat)? => $str:expr),*) => { Self::Cgen(_) => st::L_CGEN.as_sym(),
paste! { Self::Class(_) => st::L_CLASS.as_sym(),
lazy_static! { Self::Const(_, _) => st::L_CONST.as_sym(),
$( Self::Func(_, _) => st::L_FUNC.as_sym(),
static ref [<PROG_KIND_ $variant:upper>]: SymbolId Self::Gen(_, _) => st::L_GEN.as_sym(),
= $str.intern(); Self::Lparam(_, _) => st::L_LPARAM.as_sym(),
)* Self::Param(_, _) => st::L_PARAM.as_sym(),
} Self::Rate(_) => st::L_RATE.as_sym(),
Self::Tpl => st::L_TPL.as_sym(),
impl AsRef<str> for IdentKind { Self::Type(_) => st::L_TYPE.as_sym(),
fn as_ref(&self) -> &'static str { Self::MapHead => st::L_MAP_HEAD.as_sym(),
match self { Self::Map => st::L_MAP.as_sym(),
$( Self::MapTail => st::L_MAP_TAIL.as_sym(),
Self::$variant$($v)* => $str, Self::RetMapHead => st::L_RETMAP_HEAD.as_sym(),
)* Self::RetMap => st::L_RETMAP.as_sym(),
} Self::RetMapTail => st::L_RETMAP_TAIL.as_sym(),
} Self::Meta => st::L_META.as_sym(),
} Self::Worksheet => st::L_WORKSHEET.as_sym(),
impl AsRef<SymbolId> for IdentKind {
fn as_ref(&self) -> &SymbolId {
match self {
$(
Self::$variant$($v)* => &[<PROG_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 { impl std::fmt::Display for IdentKind {
/// Format identifier type for display to the user. /// Format identifier type for display to the user.
/// ///
@ -211,7 +178,7 @@ impl std::fmt::Display for IdentKind {
/// new type system, /// new type system,
/// so for now this just uses a syntax similar to Rust. /// so for now this just uses a syntax similar to Rust.
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
let name: &str = self.as_ref(); let name = self.as_sym().lookup_str();
match self { match self {
Self::Cgen(dim) => { Self::Cgen(dim) => {

View File

@ -139,20 +139,20 @@ pub fn graphml(package_path: &str, output: &str) -> Result<(), Box<dyn Error>> {
( (
format!("{}", n.name().unwrap().lookup_str()), format!("{}", n.name().unwrap().lookup_str()),
n.kind().unwrap().as_ref(), n.kind().unwrap().as_sym(),
format!("{}", generated), format!("{}", generated),
) )
} }
None => ( None => (
String::from("missing"), String::from("missing"),
"missing", "missing".into(),
format!("{}", false), format!("{}", false),
), ),
}; };
vec![ vec![
("label".into(), name.into()), ("label".into(), name.into()),
("kind".into(), kind.into()), ("kind".into(), kind.lookup_str().as_str().into()),
("generated".into(), generated.into()), ("generated".into(), generated.into()),
] ]
})); }));

View File

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

View File

@ -130,7 +130,7 @@ impl<'a, T: IdentObjectData> DepListIter<'a, T> {
self.toks_push_attr(QN_YIELDS, src.yields); self.toks_push_attr(QN_YIELDS, src.yields);
self.toks_push_attr(QN_PARENT, src.parent); self.toks_push_attr(QN_PARENT, src.parent);
self.toks_push_attr(QN_NAME, Some(sym)); self.toks_push_attr(QN_NAME, Some(sym));
self.toks_push_attr(QN_TYPE, Some(*kind.as_ref())); self.toks_push_attr(QN_TYPE, Some(kind.as_sym()));
Some(Token::Open(QN_P_SYM, LSPAN)) Some(Token::Open(QN_P_SYM, LSPAN))
}) })
@ -332,7 +332,7 @@ pub mod test {
assert_eq!( assert_eq!(
attrs.find(QN_TYPE).and_then(|a| a.value_atom()), attrs.find(QN_TYPE).and_then(|a| a.value_atom()),
Some(AttrValue::Escaped(*ident.kind().unwrap().as_ref())) Some(AttrValue::Escaped(ident.kind().unwrap().as_sym()))
); );
let generated = let generated =

View File

@ -187,6 +187,16 @@ static_symbol_newtypes! {
/// common in many programming languages. /// common in many programming languages.
cid: CIdentStaticSymbolId<global::ProgSymSize>, cid: CIdentStaticSymbolId<global::ProgSymSize>,
/// A symbol resembling a QName of the form `prefix:local`.
///
/// A symbol of this type does _not_ mean that the symbol is intended to
/// be a QName;
/// this is merely a way to describe it.
/// For example,
/// `map:head` is intended as an identifier type,
/// not a QName.
qname: QnameIdentStaticSymbolId<global::ProgSymSize>,
/// This symbol serves only as a marker in the internment pool to /// This symbol serves only as a marker in the internment pool to
/// delimit symbol ranges; /// delimit symbol ranges;
/// its string value is incidental and should not be relied upon. /// its string value is incidental and should not be relied upon.
@ -234,22 +244,39 @@ pub mod st {
static_symbols! { static_symbols! {
<global::ProgSymSize>; <global::ProgSymSize>;
L_CGEN: cid "cgen",
L_CLASS: cid "class",
L_CONST: cid "const",
L_DEP: cid "dep", L_DEP: cid "dep",
L_DESC: cid "desc", L_DESC: cid "desc",
L_FALSE: cid "false", L_FALSE: cid "false",
L_FUNC: cid "func",
L_GEN: cid "gen",
L_GENERATED: cid "generated", L_GENERATED: cid "generated",
L_L: cid "l", L_L: cid "l",
L_LPARAM: cid "lparam",
L_MAP: cid "map",
L_MAP_HEAD: qname "map:head",
L_MAP_TAIL: qname "map:tail",
L_META: cid "meta",
L_NAME: cid "name", L_NAME: cid "name",
L_PACKAGE: cid "package", L_PACKAGE: cid "package",
L_PARAM: cid "param",
L_PARENT: cid "parent", L_PARENT: cid "parent",
L_PREPROC: cid "preproc", L_PREPROC: cid "preproc",
L_PROGRAM: cid "program", L_PROGRAM: cid "program",
L_RATE: cid "rate",
L_RETMAP: cid "retmap",
L_RETMAP_HEAD: qname "retmap:head",
L_RETMAP_TAIL: qname "retmap:tail",
L_SRC: cid "src", L_SRC: cid "src",
L_SYM: cid "sym", L_SYM: cid "sym",
L_TITLE: cid "title", L_TITLE: cid "title",
L_TPL: cid "tpl",
L_TRUE: cid "true", L_TRUE: cid "true",
L_TYPE: cid "type", L_TYPE: cid "type",
L_UUROOTPATH: cid "__rootpath", L_UUROOTPATH: cid "__rootpath",
L_WORKSHEET: cid "worksheet",
L_XMLNS: cid "xmlns", L_XMLNS: cid "xmlns",
L_YIELDS: cid "yields", L_YIELDS: cid "yields",