tamer: nir::NirEntity::TplParam: Optional name/value pair

This will be used for shorthand desugaring.

DEV-13708
Mike Gerwitz 2023-03-21 15:26:17 -04:00
parent c42e693b14
commit d3f8f76904
4 changed files with 33 additions and 19 deletions

View File

@ -203,11 +203,19 @@ pub enum NirEntity {
/// Template.
Tpl,
/// Template parameter (metavariable).
TplParam,
/// Full application and expansion of the template identified by the
/// provided name.
/// Template parameter (metavariable).
///
/// If a pair of [`SPair`]s is provided,
/// then the param is shorthand,
/// with the non-`@`-padded name as the first of the pair and the
/// value as the second.
TplParam(Option<(SPair, SPair)>),
/// Full application and expansion a template.
///
/// If a name is provided,
/// then this template application is shorthand.
TplApply(Option<QName>),
}
@ -239,7 +247,13 @@ impl Display for NirEntity {
Any => write!(f, "disjunctive () expression"),
Tpl => write!(f, "template"),
TplParam => write!(f, "template param (metavariable)"),
TplParam(None) => write!(f, "template param (metavariable)"),
TplParam(Some((name, val))) => write!(
f,
"shorthand template param key {} with value {}",
TtQuote::wrap(name),
TtQuote::wrap(val),
),
TplApply(None) => {
write!(f, "full template application and expansion")
}

View File

@ -175,8 +175,8 @@ impl ParseState for NirToAir {
| Nir::TodoAttr(..)
| Nir::Desc(..)
| Nir::Text(_)
| Nir::Open(NirEntity::TplParam, _)
| Nir::Close(NirEntity::TplParam, _),
| Nir::Open(NirEntity::TplParam(_), _)
| Nir::Close(NirEntity::TplParam(_), _),
) => Transition(Ready).ok(Air::Todo(UNKNOWN_SPAN)),
}
}

View File

@ -262,7 +262,7 @@ impl ParseState for InterpState {
Ready => match tok.symbol() {
Some(sym) if needs_interpolation(sym) => {
Transition(GenIdent(sym))
.ok(Nir::Open(NirEntity::TplParam, span))
.ok(Nir::Open(NirEntity::TplParam(None), span))
.with_lookahead(tok)
}
@ -315,7 +315,7 @@ impl ParseState for InterpState {
// symbol that we've been fed
// (the specification string).
Transition(FinishSym(s, gen_param))
.ok(Nir::Close(NirEntity::TplParam, span))
.ok(Nir::Close(NirEntity::TplParam(None), span))
.with_lookahead(tok)
};
}

View File

@ -79,7 +79,7 @@ fn expect_expanded_header(
// helpful information to a human reader.
assert_eq!(
sut.next(),
Some(Ok(Object(Nir::Open(NirEntity::TplParam, span)))),
Some(Ok(Object(Nir::Open(NirEntity::TplParam(None), span)))),
);
assert_eq!(
sut.next(),
@ -132,7 +132,7 @@ fn desugars_literal_with_ending_var() {
Object(Nir::Ref(SPair("@bar@".into(), c))),
// This is an object generated from user input, so the closing
// span has to identify what were generated from.
Object(Nir::Close(NirEntity::TplParam, a)),
Object(Nir::Close(NirEntity::TplParam(None), a)),
// Finally,
// we replace the original provided attribute
// (the interpolation specification)
@ -172,7 +172,7 @@ fn desugars_var_with_ending_literal() {
Ok(vec![
Object(Nir::Ref(SPair("@foo@".into(), b))),
Object(Nir::Text(SPair("bar".into(), c))),
Object(Nir::Close(NirEntity::TplParam, a)),
Object(Nir::Close(NirEntity::TplParam(None), a)),
Object(Nir::Ref(SPair(expect_name, a))),
]),
sut.collect(),
@ -216,7 +216,7 @@ fn desugars_many_vars_and_literals() {
// offsets.
Object(Nir::Text(SPair("baz".into(), d))),
Object(Nir::Ref(SPair("@quux@".into(), e))),
Object(Nir::Close(NirEntity::TplParam, a)),
Object(Nir::Close(NirEntity::TplParam(None), a)),
Object(Nir::Ref(SPair(expect_name, a))),
]),
sut.collect(),
@ -266,7 +266,7 @@ fn proper_multibyte_handling() {
// offsets.
Object(Nir::Text(SPair("βaζ".into(), d))),
Object(Nir::Ref(SPair("@qμuχ@".into(), e))),
Object(Nir::Close(NirEntity::TplParam, a)),
Object(Nir::Close(NirEntity::TplParam(None), a)),
Object(Nir::Ref(SPair(expect_name, a))),
]),
sut.collect(),
@ -301,7 +301,7 @@ fn desugars_adjacent_interpolated_vars() {
Object(Nir::Ref(SPair("@foo@".into(), b))),
Object(Nir::Ref(SPair("@bar@".into(), c))),
Object(Nir::Ref(SPair("@baz@".into(), d))),
Object(Nir::Close(NirEntity::TplParam, a)),
Object(Nir::Close(NirEntity::TplParam(None), a)),
Object(Nir::Ref(SPair(expect_name, a))),
]),
sut.collect(),
@ -347,7 +347,7 @@ fn error_missing_closing_interp_delim() {
// Having omitted the above token,
// we're able to proceed as if the user didn't provide it at
// all.
Ok(Object(Nir::Close(NirEntity::TplParam, a))),
Ok(Object(Nir::Close(NirEntity::TplParam(None), a))),
Ok(Object(Nir::Ref(SPair(expect_name, a)))),
],
sut.collect::<Vec<ParsedResult<Sut>>>(),
@ -395,7 +395,7 @@ fn error_nested_delim() {
// (end of the specification string)
// and ignore everything that follows rather than
// potentially interpret it in confusing ways.
Ok(Object(Nir::Close(NirEntity::TplParam, a))),
Ok(Object(Nir::Close(NirEntity::TplParam(None), a))),
Ok(Object(Nir::Ref(SPair(expect_name, a)))),
],
sut.collect::<Vec<ParsedResult<Sut>>>(),
@ -438,7 +438,7 @@ fn error_empty_interp() {
// It wouldn't have had any effect anyway,
// being empty.
Ok(Object(Nir::Text(SPair("cow".into(), d)))),
Ok(Object(Nir::Close(NirEntity::TplParam, a))),
Ok(Object(Nir::Close(NirEntity::TplParam(None), a))),
Ok(Object(Nir::Ref(SPair(expect_name, a)))),
],
sut.collect::<Vec<ParsedResult<Sut>>>(),
@ -477,7 +477,7 @@ fn error_close_before_open() {
// was supposed to be a literal or a param.
// Just bail out;
// maybe in the future we can do something better.
Ok(Object(Nir::Close(NirEntity::TplParam, a))),
Ok(Object(Nir::Close(NirEntity::TplParam(None), a))),
Ok(Object(Nir::Ref(SPair(expect_name, a)))),
],
sut.collect::<Vec<ParsedResult<Sut>>>(),