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]).
use crate::ir::legacyir::{SymAttrs, SymDtype, SymType};
use crate::sym::{GlobalSymbolIntern, SymbolId};
use paste::paste;
use crate::sym::{st, GlobalSymbolResolve, SymbolId};
use std::convert::TryFrom;
use std::error::Error;
@ -147,63 +146,31 @@ pub enum IdentKind {
Worksheet,
}
/// Produce [`AsRef`] impls for [`str`] and [`global::ProgSymSize`] for
/// identifier kind strings.
macro_rules! kind_intern {
($($variant:ident $($v:pat)? => $str:expr),*) => {
paste! {
lazy_static! {
$(
static ref [<PROG_KIND_ $variant:upper>]: SymbolId
= $str.intern();
)*
}
impl AsRef<str> for IdentKind {
fn as_ref(&self) -> &'static str {
match self {
$(
Self::$variant$($v)* => $str,
)*
}
}
}
impl AsRef<SymbolId> for IdentKind {
fn as_ref(&self) -> &SymbolId {
match self {
$(
Self::$variant$($v)* => &[<PROG_KIND_ $variant:upper>],
)*
}
}
}
impl IdentKind {
pub fn as_sym(&self) -> SymbolId {
match self {
Self::Cgen(_) => st::L_CGEN.as_sym(),
Self::Class(_) => st::L_CLASS.as_sym(),
Self::Const(_, _) => st::L_CONST.as_sym(),
Self::Func(_, _) => st::L_FUNC.as_sym(),
Self::Gen(_, _) => st::L_GEN.as_sym(),
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(),
Self::Type(_) => st::L_TYPE.as_sym(),
Self::MapHead => st::L_MAP_HEAD.as_sym(),
Self::Map => st::L_MAP.as_sym(),
Self::MapTail => st::L_MAP_TAIL.as_sym(),
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(),
}
}
}
// 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.
///
@ -211,7 +178,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: &str = self.as_ref();
let name = self.as_sym().lookup_str();
match self {
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()),
n.kind().unwrap().as_ref(),
n.kind().unwrap().as_sym(),
format!("{}", generated),
)
}
None => (
String::from("missing"),
"missing",
"missing".into(),
format!("{}", false),
),
};
vec![
("label".into(), name.into()),
("kind".into(), kind.into()),
("kind".into(), kind.lookup_str().as_str().into()),
("generated".into(), generated.into()),
]
}));

View File

@ -26,6 +26,7 @@ pub mod global;
#[macro_use]
extern crate static_assertions;
#[cfg(test)]
#[macro_use]
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_PARENT, src.parent);
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))
})
@ -332,7 +332,7 @@ pub mod test {
assert_eq!(
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 =

View File

@ -187,6 +187,16 @@ static_symbol_newtypes! {
/// common in many programming languages.
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
/// delimit symbol ranges;
/// its string value is incidental and should not be relied upon.
@ -234,22 +244,39 @@ pub mod st {
static_symbols! {
<global::ProgSymSize>;
L_CGEN: cid "cgen",
L_CLASS: cid "class",
L_CONST: cid "const",
L_DEP: cid "dep",
L_DESC: cid "desc",
L_FALSE: cid "false",
L_FUNC: cid "func",
L_GEN: cid "gen",
L_GENERATED: cid "generated",
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_PACKAGE: cid "package",
L_PARAM: cid "param",
L_PARENT: cid "parent",
L_PREPROC: cid "preproc",
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_SYM: cid "sym",
L_TITLE: cid "title",
L_TPL: cid "tpl",
L_TRUE: cid "true",
L_TYPE: cid "type",
L_UUROOTPATH: cid "__rootpath",
L_WORKSHEET: cid "worksheet",
L_XMLNS: cid "xmlns",
L_YIELDS: cid "yields",