tame: obj::xmlo: Use SPair where applicable
This simply pairs the individual `SymbolId` and `Span`. Rationale for this pairing was added as documentation to `SPair`. DEV-13430main
parent
c71f3247b1
commit
af91857746
|
@ -84,7 +84,7 @@ impl XmloAirContext {
|
|||
}
|
||||
}
|
||||
|
||||
type PackageName = SymbolId;
|
||||
type PackageSPair = SPair;
|
||||
|
||||
/// State machine for lowering into the [`Asg`](crate::asg::Asg) via
|
||||
/// [`Air`].
|
||||
|
@ -92,8 +92,8 @@ type PackageName = SymbolId;
|
|||
pub enum XmloToAir {
|
||||
#[default]
|
||||
PackageExpected,
|
||||
Package(PackageName, Span),
|
||||
SymDep(PackageName, Span, SPair),
|
||||
Package(PackageSPair),
|
||||
SymDep(PackageSPair, SPair),
|
||||
/// End of header (EOH) reached.
|
||||
Done(Span),
|
||||
}
|
||||
|
@ -113,17 +113,17 @@ impl ParseState for XmloToAir {
|
|||
use XmloToAir::*;
|
||||
|
||||
match (self, tok) {
|
||||
(PackageExpected, XmloToken::PkgName(name, span)) => {
|
||||
(PackageExpected, XmloToken::PkgName(name)) => {
|
||||
if ctx.is_first() {
|
||||
ctx.prog_name = Some(name);
|
||||
ctx.prog_name = Some(name.symbol());
|
||||
}
|
||||
|
||||
Transition(Package(name, span)).incomplete()
|
||||
Transition(Package(name)).incomplete()
|
||||
}
|
||||
|
||||
(st @ Package(..), XmloToken::PkgRootPath(relroot, _)) => {
|
||||
(st @ Package(..), XmloToken::PkgRootPath(relroot)) => {
|
||||
if ctx.is_first() {
|
||||
ctx.relroot = Some(relroot);
|
||||
ctx.relroot = Some(relroot.symbol());
|
||||
}
|
||||
|
||||
Transition(st).incomplete()
|
||||
|
@ -135,16 +135,12 @@ impl ParseState for XmloToAir {
|
|||
// definition is encountered later within the same file.
|
||||
// TODO: Let's remove the need for this special root handling
|
||||
// here.
|
||||
(
|
||||
Package(pkg_name, span),
|
||||
XmloToken::PkgEligClassYields(pkg_elig, elig_span),
|
||||
) => {
|
||||
(Package(name), XmloToken::PkgEligClassYields(pkg_elig)) => {
|
||||
// The span for this is a bit awkward,
|
||||
// given that rooting is automatic,
|
||||
// but it it should never have to be utilized in
|
||||
// diagnostics unless there is a compiler bug.
|
||||
Transition(Package(pkg_name, span))
|
||||
.ok(Air::IdentRoot(SPair(pkg_elig, elig_span)))
|
||||
Transition(Package(name)).ok(Air::IdentRoot(pkg_elig))
|
||||
}
|
||||
|
||||
(
|
||||
|
@ -156,35 +152,29 @@ impl ParseState for XmloToAir {
|
|||
}
|
||||
|
||||
(
|
||||
Package(pkg_name, span) | SymDep(pkg_name, span, ..),
|
||||
XmloToken::SymDepStart(sym, sym_span),
|
||||
) => Transition(SymDep(pkg_name, span, SPair(sym, sym_span)))
|
||||
.incomplete(),
|
||||
Package(pkg_name) | SymDep(pkg_name, ..),
|
||||
XmloToken::SymDepStart(sym),
|
||||
) => Transition(SymDep(pkg_name, sym)).incomplete(),
|
||||
|
||||
(
|
||||
SymDep(pkg_name, span, sym),
|
||||
XmloToken::Symbol(dep_sym, dep_span),
|
||||
) => Transition(SymDep(pkg_name, span, sym))
|
||||
.ok(Air::IdentDep(sym, SPair(dep_sym, dep_span))),
|
||||
|
||||
(
|
||||
Package(pkg_name, span),
|
||||
XmloToken::SymDecl(
|
||||
_sym,
|
||||
SymAttrs {
|
||||
src: Some(sym_src), ..
|
||||
},
|
||||
_span,
|
||||
),
|
||||
) => {
|
||||
ctx.found.get_or_insert(Default::default()).insert(sym_src);
|
||||
Transition(Package(pkg_name, span)).incomplete()
|
||||
(SymDep(pkg_name, sym), XmloToken::Symbol(dep_sym)) => {
|
||||
Transition(SymDep(pkg_name, sym))
|
||||
.ok(Air::IdentDep(sym, dep_sym))
|
||||
}
|
||||
|
||||
(
|
||||
Package(pkg_name, span),
|
||||
XmloToken::SymDecl(sym, attrs, sym_span),
|
||||
Package(pkg_name),
|
||||
XmloToken::SymDecl(
|
||||
_name,
|
||||
SymAttrs {
|
||||
src: Some(sym_src), ..
|
||||
},
|
||||
),
|
||||
) => {
|
||||
ctx.found.get_or_insert(Default::default()).insert(sym_src);
|
||||
Transition(Package(pkg_name)).incomplete()
|
||||
}
|
||||
|
||||
(Package(pkg_name), XmloToken::SymDecl(name, attrs)) => {
|
||||
let extern_ = attrs.extern_;
|
||||
|
||||
// TODO: This attr/source separation is a mess,
|
||||
|
@ -197,7 +187,7 @@ impl ParseState for XmloToAir {
|
|||
|
||||
// This used to come from SymAttrs in the old XmloReader.
|
||||
if src.pkg_name.is_none() {
|
||||
src.pkg_name.replace(pkg_name);
|
||||
src.pkg_name.replace(pkg_name.symbol());
|
||||
}
|
||||
|
||||
// Existing convention is to omit @src of local package
|
||||
|
@ -208,26 +198,23 @@ impl ParseState for XmloToAir {
|
|||
|
||||
if extern_ {
|
||||
Ok(ParseStatus::Object(Air::IdentExternDecl(
|
||||
SPair(sym, sym_span),
|
||||
kindval,
|
||||
src,
|
||||
name, kindval, src,
|
||||
)))
|
||||
} else {
|
||||
Ok(ParseStatus::Object(Air::IdentDecl(
|
||||
SPair(sym, sym_span),
|
||||
kindval,
|
||||
src,
|
||||
name, kindval, src,
|
||||
)))
|
||||
}
|
||||
})
|
||||
.transition(Package(pkg_name, span))
|
||||
.transition(Package(pkg_name))
|
||||
}
|
||||
|
||||
(
|
||||
Package(pkg_name, span) | SymDep(pkg_name, span, _),
|
||||
XmloToken::Fragment(sym, text, frag_span),
|
||||
) => Transition(Package(pkg_name, span))
|
||||
.ok(Air::IdentFragment(SPair(sym, frag_span), text)),
|
||||
Package(pkg_name) | SymDep(pkg_name, _),
|
||||
XmloToken::Fragment(name, text),
|
||||
) => {
|
||||
Transition(Package(pkg_name)).ok(Air::IdentFragment(name, text))
|
||||
}
|
||||
|
||||
// We don't need to read any further than the end of the
|
||||
// header (symtable, sym-deps, fragments).
|
||||
|
@ -257,10 +244,10 @@ impl Display for XmloToAir {
|
|||
|
||||
match self {
|
||||
PackageExpected => write!(f, "expecting package definition"),
|
||||
Package(name, _) => {
|
||||
Package(name) => {
|
||||
write!(f, "expecting package `/{name}` declarations")
|
||||
}
|
||||
SymDep(pkg_name, _, sym) => {
|
||||
SymDep(pkg_name, sym) => {
|
||||
write!(f, "expecting dependency for symbol `/{pkg_name}/{sym}`")
|
||||
}
|
||||
Done(_) => write!(f, "done lowering xmlo into AIR"),
|
||||
|
@ -423,8 +410,8 @@ mod test {
|
|||
let relroot = "some/path".into();
|
||||
|
||||
let toks = vec![
|
||||
XmloToken::PkgName(name, S1),
|
||||
XmloToken::PkgRootPath(relroot, S2),
|
||||
XmloToken::PkgName(SPair(name, S1)),
|
||||
XmloToken::PkgRootPath(SPair(relroot, S2)),
|
||||
XmloToken::Eoh(S3),
|
||||
]
|
||||
.into_iter();
|
||||
|
@ -447,8 +434,8 @@ mod test {
|
|||
let elig_sym = "elig".into();
|
||||
|
||||
let toks = vec![
|
||||
XmloToken::PkgName(name, S1),
|
||||
XmloToken::PkgEligClassYields(elig_sym, S2),
|
||||
XmloToken::PkgName(SPair(name, S1)),
|
||||
XmloToken::PkgEligClassYields(SPair(elig_sym, S2)),
|
||||
XmloToken::Eoh(S3),
|
||||
];
|
||||
|
||||
|
@ -469,10 +456,10 @@ mod test {
|
|||
let sym_to2 = "to2".into();
|
||||
|
||||
let toks = vec![
|
||||
XmloToken::PkgName("name".into(), S1),
|
||||
XmloToken::SymDepStart(sym_from, S2),
|
||||
XmloToken::Symbol(sym_to1, S3),
|
||||
XmloToken::Symbol(sym_to2, S4),
|
||||
XmloToken::PkgName(SPair("name".into(), S1)),
|
||||
XmloToken::SymDepStart(SPair(sym_from, S2)),
|
||||
XmloToken::Symbol(SPair(sym_to1, S3)),
|
||||
XmloToken::Symbol(SPair(sym_to2, S4)),
|
||||
XmloToken::Eoh(S1),
|
||||
];
|
||||
|
||||
|
@ -501,22 +488,20 @@ mod test {
|
|||
let src_b = "src_b".into();
|
||||
|
||||
let toks = vec![
|
||||
XmloToken::PkgName("name".into(), S1),
|
||||
XmloToken::PkgName(SPair("name".into(), S1)),
|
||||
XmloToken::SymDecl(
|
||||
sym,
|
||||
SPair(sym, S2),
|
||||
SymAttrs {
|
||||
src: Some(src_a),
|
||||
..Default::default()
|
||||
},
|
||||
S2,
|
||||
),
|
||||
XmloToken::SymDecl(
|
||||
sym,
|
||||
SPair(sym, S3),
|
||||
SymAttrs {
|
||||
src: Some(src_b),
|
||||
..Default::default()
|
||||
},
|
||||
S3,
|
||||
),
|
||||
XmloToken::Eoh(S1),
|
||||
];
|
||||
|
@ -547,43 +532,39 @@ mod test {
|
|||
let pkg_name = "pkg name".into();
|
||||
|
||||
let toks = vec![
|
||||
XmloToken::PkgName("name".into(), S1),
|
||||
XmloToken::PkgName(SPair("name".into(), S1)),
|
||||
XmloToken::SymDecl(
|
||||
sym_extern,
|
||||
SPair(sym_extern, S1),
|
||||
SymAttrs {
|
||||
pkg_name: Some(pkg_name),
|
||||
extern_: true,
|
||||
ty: Some(SymType::Meta),
|
||||
..Default::default()
|
||||
},
|
||||
S1,
|
||||
),
|
||||
XmloToken::SymDecl(
|
||||
sym_non_extern,
|
||||
SPair(sym_non_extern, S2),
|
||||
SymAttrs {
|
||||
pkg_name: Some(pkg_name),
|
||||
ty: Some(SymType::Meta),
|
||||
..Default::default()
|
||||
},
|
||||
S2,
|
||||
),
|
||||
XmloToken::SymDecl(
|
||||
sym_map,
|
||||
SPair(sym_map, S3),
|
||||
SymAttrs {
|
||||
pkg_name: Some(pkg_name),
|
||||
ty: Some(SymType::Map),
|
||||
..Default::default()
|
||||
},
|
||||
S3,
|
||||
),
|
||||
XmloToken::SymDecl(
|
||||
sym_retmap,
|
||||
SPair(sym_retmap, S4),
|
||||
SymAttrs {
|
||||
pkg_name: Some(pkg_name),
|
||||
ty: Some(SymType::RetMap),
|
||||
..Default::default()
|
||||
},
|
||||
S4,
|
||||
),
|
||||
XmloToken::Eoh(S1),
|
||||
];
|
||||
|
@ -662,15 +643,14 @@ mod test {
|
|||
};
|
||||
|
||||
let toks = vec![
|
||||
XmloToken::PkgName(pkg_name, S1),
|
||||
XmloToken::PkgName(SPair(pkg_name, S1)),
|
||||
XmloToken::SymDecl(
|
||||
sym,
|
||||
SPair(sym, S2),
|
||||
SymAttrs {
|
||||
pkg_name: Some(pkg_name),
|
||||
ty: Some(SymType::Meta),
|
||||
..Default::default()
|
||||
},
|
||||
S2,
|
||||
),
|
||||
XmloToken::Eoh(S1),
|
||||
];
|
||||
|
@ -705,15 +685,14 @@ mod test {
|
|||
};
|
||||
|
||||
let toks = vec![
|
||||
XmloToken::PkgName(pkg_name, S1),
|
||||
XmloToken::PkgName(SPair(pkg_name, S1)),
|
||||
XmloToken::SymDecl(
|
||||
sym,
|
||||
SPair(sym, S2),
|
||||
SymAttrs {
|
||||
// No name
|
||||
ty: Some(SymType::Meta),
|
||||
..Default::default()
|
||||
},
|
||||
S2,
|
||||
),
|
||||
XmloToken::Eoh(S1),
|
||||
];
|
||||
|
@ -741,8 +720,8 @@ mod test {
|
|||
let bad_attrs = SymAttrs::default();
|
||||
|
||||
let toks = vec![
|
||||
XmloToken::PkgName("name".into(), S1),
|
||||
XmloToken::SymDecl(sym, bad_attrs, S2),
|
||||
XmloToken::PkgName(SPair("name".into(), S1)),
|
||||
XmloToken::SymDecl(SPair(sym, S2), bad_attrs),
|
||||
XmloToken::Eoh(S1),
|
||||
];
|
||||
|
||||
|
@ -757,8 +736,8 @@ mod test {
|
|||
let frag = FragmentText::from("foo");
|
||||
|
||||
let toks = vec![
|
||||
XmloToken::PkgName("name".into(), S1),
|
||||
XmloToken::Fragment(sym, frag.clone(), S2),
|
||||
XmloToken::PkgName(SPair("name".into(), S1)),
|
||||
XmloToken::Fragment(SPair(sym, S2), frag.clone()),
|
||||
XmloToken::Eoh(S1),
|
||||
];
|
||||
|
||||
|
|
|
@ -21,11 +21,12 @@ use std::fmt::Display;
|
|||
|
||||
use super::{SymAttrs, XmloError};
|
||||
use crate::{
|
||||
fmt::{DisplayWrapper, TtQuote},
|
||||
num::{Dim, Dtype},
|
||||
obj::xmlo::SymType,
|
||||
parse::{
|
||||
self, ClosedParseState, EmptyContext, NoContext, ParseState, Token,
|
||||
Transition, TransitionResult, Transitionable,
|
||||
self, util::SPair, ClosedParseState, EmptyContext, NoContext,
|
||||
ParseState, Token, Transition, TransitionResult, Transitionable,
|
||||
},
|
||||
span::Span,
|
||||
sym::{st::raw, SymbolId},
|
||||
|
@ -49,24 +50,24 @@ use crate::{
|
|||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum XmloToken {
|
||||
/// Canonical package name.
|
||||
PkgName(SymbolId, Span),
|
||||
PkgName(SPair),
|
||||
/// Relative path from package to project root.
|
||||
PkgRootPath(SymbolId, Span),
|
||||
PkgRootPath(SPair),
|
||||
/// Indicates that the package is a program.
|
||||
PkgProgramFlag(Span),
|
||||
/// Name of package eligibility classification.
|
||||
PkgEligClassYields(SymbolId, Span),
|
||||
PkgEligClassYields(SPair),
|
||||
|
||||
/// Symbol declaration.
|
||||
///
|
||||
/// This represents an entry in the symbol table,
|
||||
/// which includes a symbol along with its variable metadata as
|
||||
/// [`SymAttrs`].
|
||||
SymDecl(SymbolId, SymAttrs, Span),
|
||||
SymDecl(SPair, SymAttrs),
|
||||
|
||||
/// Begin adjacency list for a given symbol and interpret subsequent
|
||||
/// symbols as edges (dependencies).
|
||||
SymDepStart(SymbolId, Span),
|
||||
SymDepStart(SPair),
|
||||
|
||||
/// A symbol reference whose interpretation is dependent on the current
|
||||
/// state.
|
||||
|
@ -74,7 +75,7 @@ pub enum XmloToken {
|
|||
/// The span currently references the object file itself,
|
||||
/// but in the future this will resolve to a span stored within the
|
||||
/// object file representing the source location of this symbol.
|
||||
Symbol(SymbolId, Span),
|
||||
Symbol(SPair),
|
||||
|
||||
/// Text (compiled code) fragment for a given symbol.
|
||||
///
|
||||
|
@ -83,7 +84,7 @@ pub enum XmloToken {
|
|||
/// Given that fragments can be quite large,
|
||||
/// a caller not interested in these data should choose to skip
|
||||
/// fragments entirely rather than simply ignoring fragment events.
|
||||
Fragment(SymbolId, SymbolId, Span),
|
||||
Fragment(SPair, SymbolId),
|
||||
|
||||
/// End-of-header.
|
||||
///
|
||||
|
@ -108,14 +109,14 @@ impl Token for XmloToken {
|
|||
// important since these initial tokens seed
|
||||
// `Parser::last_span`,
|
||||
// which is used for early error messages.
|
||||
PkgName(_, span)
|
||||
| PkgRootPath(_, span)
|
||||
PkgName(SPair(_, span))
|
||||
| PkgRootPath(SPair(_, span))
|
||||
| PkgProgramFlag(span)
|
||||
| PkgEligClassYields(_, span)
|
||||
| SymDecl(.., span)
|
||||
| SymDepStart(.., span)
|
||||
| Symbol(.., span)
|
||||
| Fragment(.., span)
|
||||
| PkgEligClassYields(SPair(_, span))
|
||||
| SymDecl(SPair(_, span), _)
|
||||
| SymDepStart(SPair(_, span))
|
||||
| Symbol(SPair(_, span))
|
||||
| Fragment(SPair(_, span), _)
|
||||
| Eoh(span) => *span,
|
||||
}
|
||||
}
|
||||
|
@ -126,18 +127,32 @@ impl Display for XmloToken {
|
|||
use XmloToken::*;
|
||||
|
||||
match self {
|
||||
PkgName(sym, _) => write!(f, "package name `{sym}`"),
|
||||
PkgRootPath(sym, _) => write!(f, "package root path `{sym}`"),
|
||||
PkgName(sym) => write!(f, "package of name {}", TtQuote::wrap(sym)),
|
||||
PkgRootPath(sym) => {
|
||||
write!(f, "package root path {}", TtQuote::wrap(sym))
|
||||
}
|
||||
PkgProgramFlag(_) => write!(f, "package program flag"),
|
||||
PkgEligClassYields(sym, _) => {
|
||||
write!(f, "package eligibility classification `{sym}`")
|
||||
PkgEligClassYields(sym) => {
|
||||
write!(
|
||||
f,
|
||||
"package eligibility classification {}",
|
||||
TtQuote::wrap(sym)
|
||||
)
|
||||
}
|
||||
SymDecl(sym, ..) => write!(f, "symbol `{sym}` declaration"),
|
||||
SymDepStart(sym, ..) => {
|
||||
write!(f, "beginning of symbol `{sym}` dependency list")
|
||||
SymDecl(sym, ..) => {
|
||||
write!(f, "symbol {} declaration", TtQuote::wrap(sym))
|
||||
}
|
||||
SymDepStart(sym) => {
|
||||
write!(
|
||||
f,
|
||||
"beginning of symbol {} dependency list",
|
||||
TtQuote::wrap(sym)
|
||||
)
|
||||
}
|
||||
Symbol(sym) => write!(f, "symbol {}", TtQuote::wrap(sym)),
|
||||
Fragment(sym, _) => {
|
||||
write!(f, "symbol {} code fragment", TtQuote::wrap(sym))
|
||||
}
|
||||
Symbol(sym, ..) => write!(f, "symbol `{sym}`"),
|
||||
Fragment(sym, ..) => write!(f, "symbol `{sym}` code fragment"),
|
||||
Eoh(..) => write!(f, "end of header"),
|
||||
}
|
||||
}
|
||||
|
@ -206,12 +221,16 @@ impl<SS: XmloState, SD: XmloState, SF: XmloState> ParseState
|
|||
// which can result in confusing output depending on the context;
|
||||
// we ought to retain _both_ token- and value-spans.
|
||||
Transition(Package(span)).ok(match name {
|
||||
QN_NAME => XmloToken::PkgName(value, aspan.1),
|
||||
QN_UUROOTPATH => XmloToken::PkgRootPath(value, aspan.1),
|
||||
QN_PROGRAM => XmloToken::PkgProgramFlag(aspan.0), // yes 0
|
||||
QN_P_ELIG_CLASS_YIELDS => {
|
||||
XmloToken::PkgEligClassYields(value, aspan.1)
|
||||
QN_NAME => {
|
||||
XmloToken::PkgName(SPair(value, aspan.value_span()))
|
||||
}
|
||||
QN_UUROOTPATH => {
|
||||
XmloToken::PkgRootPath(SPair(value, aspan.value_span()))
|
||||
}
|
||||
QN_PROGRAM => XmloToken::PkgProgramFlag(aspan.key_span()),
|
||||
QN_P_ELIG_CLASS_YIELDS => XmloToken::PkgEligClassYields(
|
||||
SPair(value, aspan.value_span()),
|
||||
),
|
||||
// Ignore unknown attributes for now to maintain BC,
|
||||
// since no strict xmlo schema has been defined.
|
||||
_ => return Transition(Package(span)).incomplete(),
|
||||
|
@ -335,11 +354,9 @@ pub enum SymtableState {
|
|||
SymRef(Span, SymbolId, SymAttrs, Span),
|
||||
}
|
||||
|
||||
impl parse::Object for (SymbolId, SymAttrs, Span) {}
|
||||
|
||||
impl ParseState for SymtableState {
|
||||
type Token = Xirf<Text>;
|
||||
type Object = (SymbolId, SymAttrs, Span);
|
||||
type Object = XmloToken;
|
||||
type Error = XmloError;
|
||||
|
||||
fn parse_token(
|
||||
|
@ -364,7 +381,8 @@ impl ParseState for SymtableState {
|
|||
|
||||
// Completed symbol.
|
||||
(Sym(span, Some(name), attrs), Xirf::Close(..)) => {
|
||||
Transition(Ready).ok((name, attrs, span))
|
||||
Transition(Ready)
|
||||
.ok(XmloToken::SymDecl(SPair(name, span), attrs))
|
||||
}
|
||||
|
||||
// Symbol @name found.
|
||||
|
@ -597,14 +615,6 @@ impl Display for SymtableState {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<(SymbolId, SymAttrs, Span)> for XmloToken {
|
||||
fn from(tup: (SymbolId, SymAttrs, Span)) -> Self {
|
||||
match tup {
|
||||
(sym, attrs, span) => Self::SymDecl(sym, attrs, span),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Symbol dependency list (graph adjacency list) parser for
|
||||
/// `preproc:sym-deps` children.
|
||||
///
|
||||
|
@ -645,7 +655,7 @@ impl ParseState for SymDepsState {
|
|||
|
||||
(SymUnnamed(span), Xirf::Attr(Attr(QN_NAME, name, _))) => {
|
||||
Transition(Sym(span, name))
|
||||
.ok(XmloToken::SymDepStart(name, span))
|
||||
.ok(XmloToken::SymDepStart(SPair(name, span)))
|
||||
}
|
||||
|
||||
(SymUnnamed(span), _) => Transition(SymUnnamed(span))
|
||||
|
@ -660,7 +670,7 @@ impl ParseState for SymDepsState {
|
|||
SymRefUnnamed(span, name, span_ref),
|
||||
Xirf::Attr(Attr(QN_NAME, ref_name, AttrSpan(_, span_ref_name))),
|
||||
) => Transition(SymRefDone(span, name, span_ref))
|
||||
.ok(XmloToken::Symbol(ref_name, span_ref_name)),
|
||||
.ok(XmloToken::Symbol(SPair(ref_name, span_ref_name))),
|
||||
|
||||
// TODO: For xmlns attributes, which will go away in XIRF.
|
||||
(SymRefUnnamed(span, name, span_ref), Xirf::Attr(..)) => {
|
||||
|
@ -731,8 +741,8 @@ pub enum FragmentsState {
|
|||
#[default]
|
||||
Ready,
|
||||
FragmentUnnamed(Span),
|
||||
Fragment(Span, SymbolId),
|
||||
FragmentDone(Span, SymbolId),
|
||||
Fragment(SPair),
|
||||
FragmentDone(SPair),
|
||||
}
|
||||
|
||||
impl ParseState for FragmentsState {
|
||||
|
@ -763,7 +773,7 @@ impl ParseState for FragmentsState {
|
|||
raw::WS_EMPTY => {
|
||||
Transition(FragmentUnnamed(span)).incomplete()
|
||||
}
|
||||
id => Transition(Fragment(span, id)).incomplete(),
|
||||
id => Transition(Fragment(SPair(id, span))).incomplete(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -781,14 +791,14 @@ impl ParseState for FragmentsState {
|
|||
(FragmentUnnamed(span), _) => Transition(FragmentUnnamed(span))
|
||||
.err(XmloError::UnassociatedFragment(span)),
|
||||
|
||||
(Fragment(span, id), Xirf::Text(Text(text, _), _)) => {
|
||||
Transition(FragmentDone(span, id))
|
||||
.ok(XmloToken::Fragment(id, text, span))
|
||||
(Fragment(name), Xirf::Text(Text(text, _), _)) => {
|
||||
Transition(FragmentDone(name))
|
||||
.ok(XmloToken::Fragment(name, text))
|
||||
}
|
||||
|
||||
// TODO: Also a compiler bug, for some generated classes.
|
||||
// This needs fixing in the compiler.
|
||||
(Fragment(_span, _id), Xirf::Close(..)) => {
|
||||
(Fragment(_), Xirf::Close(..)) => {
|
||||
//eprintln!("warning: empty fragment text for {id} at {span}");
|
||||
Transition(Ready).incomplete()
|
||||
}
|
||||
|
@ -817,11 +827,19 @@ impl Display for FragmentsState {
|
|||
FragmentUnnamed(_) => {
|
||||
write!(f, "expecting fragment association id")
|
||||
}
|
||||
Fragment(_, sym) => {
|
||||
write!(f, "expecting fragment text for symbol `{sym}`")
|
||||
Fragment(name) => {
|
||||
write!(
|
||||
f,
|
||||
"expecting fragment text for symbol {}",
|
||||
TtQuote::wrap(name)
|
||||
)
|
||||
}
|
||||
FragmentDone(_, sym) => {
|
||||
write!(f, "expecting end of fragment for symbol `{sym}`")
|
||||
FragmentDone(name) => {
|
||||
write!(
|
||||
f,
|
||||
"expecting end of fragment for symbol {}",
|
||||
TtQuote::wrap(name)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,14 +79,14 @@ fn common_parses_package_attrs(package: QName) {
|
|||
assert_eq!(
|
||||
Ok(vec![
|
||||
Parsed::Incomplete,
|
||||
Parsed::Object(XmloToken::PkgName(name, S3)),
|
||||
Parsed::Object(XmloToken::PkgRootPath(relroot, S3)),
|
||||
Parsed::Object(XmloToken::PkgName(SPair(name, S3))),
|
||||
Parsed::Object(XmloToken::PkgRootPath(SPair(relroot, S3))),
|
||||
// Span for the program flag is the attr name,
|
||||
// rather than the value,
|
||||
// since the value is just a boolean and does not provide as
|
||||
// useful of context.
|
||||
Parsed::Object(XmloToken::PkgProgramFlag(S3)),
|
||||
Parsed::Object(XmloToken::PkgEligClassYields(elig, S4)),
|
||||
Parsed::Object(XmloToken::PkgEligClassYields(SPair(elig, S4))),
|
||||
Parsed::Incomplete,
|
||||
]),
|
||||
sut.collect(),
|
||||
|
@ -125,7 +125,7 @@ fn ignores_unknown_package_attr() {
|
|||
assert_eq!(
|
||||
Ok(vec![
|
||||
Parsed::Incomplete,
|
||||
Parsed::Object(XmloToken::PkgName(name, S3)),
|
||||
Parsed::Object(XmloToken::PkgName(SPair(name, S3))),
|
||||
Parsed::Incomplete, // The unknown attribute
|
||||
Parsed::Incomplete,
|
||||
]),
|
||||
|
@ -191,7 +191,10 @@ macro_rules! symtable_tests {
|
|||
#[doc=stringify!($key)]
|
||||
Parsed::Incomplete,
|
||||
)*
|
||||
Parsed::Object((name, expected, S3)),
|
||||
Parsed::Object(XmloToken::SymDecl(
|
||||
SPair(name, S3),
|
||||
expected
|
||||
)),
|
||||
]),
|
||||
Err(expected) => Err(ParseError::StateError(expected)),
|
||||
},
|
||||
|
@ -345,7 +348,7 @@ fn symtable_sym_generated_true() {
|
|||
Parsed::Incomplete, // Opening tag
|
||||
Parsed::Incomplete, // @name
|
||||
Parsed::Incomplete, // @preproc:generated
|
||||
Parsed::Object((name, expected, S3)),
|
||||
Parsed::Object(XmloToken::SymDecl(SPair(name, S3), expected)),
|
||||
]),
|
||||
SymtableState::parse(toks).collect(),
|
||||
);
|
||||
|
@ -385,7 +388,7 @@ fn symtable_map_from() {
|
|||
Parsed::Incomplete, // <preproc:from
|
||||
Parsed::Incomplete, // @name
|
||||
Parsed::Incomplete, // />
|
||||
Parsed::Object((name, expected, S3)),
|
||||
Parsed::Object(XmloToken::SymDecl(SPair(name, S3), expected)),
|
||||
]),
|
||||
SymtableState::parse(toks).collect(),
|
||||
);
|
||||
|
@ -471,12 +474,12 @@ fn sym_dep_event() {
|
|||
assert_eq!(
|
||||
Ok(vec![
|
||||
Parsed::Incomplete, // <preproc:sym-ref
|
||||
Parsed::Object(XmloToken::SymDepStart(name, S1)), // @name
|
||||
Parsed::Object(XmloToken::SymDepStart(SPair(name, S1))), // @name
|
||||
Parsed::Incomplete, // <preproc:sym-ref
|
||||
Parsed::Object(XmloToken::Symbol(dep1, S4)), // @name
|
||||
Parsed::Object(XmloToken::Symbol(SPair(dep1, S4))), // @name
|
||||
Parsed::Incomplete, // />
|
||||
Parsed::Incomplete, // <preproc:sym-ref
|
||||
Parsed::Object(XmloToken::Symbol(dep2, S5)), // @name
|
||||
Parsed::Object(XmloToken::Symbol(SPair(dep2, S5))), // @name
|
||||
Parsed::Incomplete, // />
|
||||
Parsed::Incomplete, // </preproc:sym-dep>
|
||||
]),
|
||||
|
@ -545,11 +548,11 @@ fn sym_fragment_event() {
|
|||
Ok(vec![
|
||||
Parsed::Incomplete, // <preproc:fragment
|
||||
Parsed::Incomplete, // @id
|
||||
Parsed::Object(XmloToken::Fragment(id1, frag1, S1)), // text
|
||||
Parsed::Object(XmloToken::Fragment(SPair(id1, S1), frag1)), // text
|
||||
Parsed::Incomplete, // </preproc:fragment>
|
||||
Parsed::Incomplete, // <preproc:fragment
|
||||
Parsed::Incomplete, // @id
|
||||
Parsed::Object(XmloToken::Fragment(id2, frag2, S2)), // text
|
||||
Parsed::Object(XmloToken::Fragment(SPair(id2, S2), frag2)), // text
|
||||
Parsed::Incomplete, // </preproc:fragment>
|
||||
]),
|
||||
FragmentsState::parse(toks).collect()
|
||||
|
@ -664,12 +667,11 @@ fn xmlo_composite_parsers_header() {
|
|||
assert_eq!(
|
||||
Ok(vec![
|
||||
Parsed::Object(XmloToken::SymDecl(
|
||||
sym_name,
|
||||
SPair(sym_name, S3),
|
||||
Default::default(),
|
||||
S3
|
||||
)),
|
||||
Parsed::Object(XmloToken::SymDepStart(symdep_name, S3)),
|
||||
Parsed::Object(XmloToken::Fragment(symfrag_id, frag, S4)),
|
||||
Parsed::Object(XmloToken::SymDepStart(SPair(symdep_name, S3))),
|
||||
Parsed::Object(XmloToken::Fragment(SPair(symfrag_id, S4), frag)),
|
||||
Parsed::Object(XmloToken::Eoh(S3)),
|
||||
]),
|
||||
sut.filter(|parsed| match parsed {
|
||||
|
|
|
@ -37,6 +37,20 @@ use std::fmt::Display;
|
|||
/// (such as [`Display`])
|
||||
/// cannot be implemented on tuples at the time of writing.
|
||||
///
|
||||
/// This type provides some notable benefits:
|
||||
///
|
||||
/// - [`Display`]ing an [`SPair`] will render the [`SymbolId`]'s
|
||||
/// interned string,
|
||||
/// and the same [`SPair`] when used with
|
||||
/// [`crate::diagnose::Annotate`] will provide annotated spans;
|
||||
/// this allows [`SPair`] to be used without destructuring in
|
||||
/// diagnostic messages.
|
||||
/// - [`Span`]s are explicitly coupled with their corresponding
|
||||
/// [`SymbolId`],
|
||||
/// reducing complexity when many spans are in play.
|
||||
/// - [`SPair`] implements [`Token`],
|
||||
/// and so can serve as an ad-hoc IR if appropriate.
|
||||
///
|
||||
/// This implements [`Copy`] because each inner type is small
|
||||
/// (and itself [`Copy`]),
|
||||
/// and in practice,
|
||||
|
|
Loading…
Reference in New Issue