tamer: NIR re-simplification

Alright, this has been a rather tortured experience.  The previous commit
began to state what is going on.

This is reversing a lot of prior work, with the benefit of
hindsight.  Little bit of history, for the people who will probably never
read this, but who knows:

As noted at the top of NIR, I've long wanted a very simple set of general
primitives where all desugaring is done by the template system---TAME is a
metalanguage after all.  Therefore, I never intended on having any explicit
desugaring operations.

But I didn't have time to augment the template system to support parsing on
attribute strings (nor am I sure if I want to do such a thing), so it became
clear that interpolation would be a pass in the compiler.  Which led me to
the idea of a desugaring pass.

That in turn spiraled into representing the status of whether NIR was
desugared, and separating primitives, etc, which lead to a lot of additional
complexity.  The idea was to have a Sugared and Plan NIR, and further within
them have symbols that have latent types---if they require interpolation,
then those types would be deferred until after template expansion.

The obvious problem there is that now:

  1. NIR has the complexity of various types; and
  2. Types were tightly coupled with NIR and how it was defined in terms of
     XML destructuring.

The first attempt at this didn't go well: it was clear that the symbol types
would make mapping from Sugared to Plain NIR very complicated.  Further,
since NIR had any number of symbols per Sugared NIR token, interpolation was
a pain in the ass.

So that lead to the idea of interpolating at the _attribute_ level.  That
seemed to be going well at first, until I realized that the token stream of
the attribute parser does not match that of the element parser, and so that
general solution fell apart.  It wouldn't have been great anyway, since then
interpolation was _also_ coupled to the destructuring of the document.

Another goal of mine has been to decouple TAME from XML.  Not because I want
to move away from XML (if I did, I'd want S-expressions, not YAML, but I
don't think the team would go for that).  This decoupling would allow the
use of a subset of the syntax of TAME in other places, like CSVMs and YAML
test cases, for example, if appropriate.

This approach makes sense: the grammar of TAME isn't XML, it's _embedded
within_ XML.  The XML layer has to be stripped to expose it.

And so that's what NIR is now evolving into---the stripped, bare
repsentation of TAME's language.  That also has other benefits too down the
line, like a REPL where you can use any number of syntaxes.  I intend for
NIR to be stack-based, which I'd find to be intuitive for manipulating and
querying packages, but it could have any number of grammars, including
Prolog-like for expressing Horn clauses and querying with a
Prolog/Datalog-like syntax.  But that's for the future...

The next issue is that of attribute types.  If we have a better language for
NIR, then the types can be associated with the NIR tokens, rather than
having to associate each symbol with raw type data, which doesn't make a
whole lot of sense.  That also allows for AIR to better infer types and
determine what they ought to be, and further makes checking types after
template application natural, since it's not part of NIR at all.  It also
means the template system can naturally apply to any sources.

Now, if we take that final step further, and make attributes streaming
instead of aggregating, we're back to a streaming pipeline where all
aggregation takes place on the ASG (which also resolves the memcpy concerns
worked around previously, also further simplifying `ele_parse` again, though
it sucks that I wasted that time).  And, without the symbol types getting
in the way, since now NIR has types more fundamentally associated with
tokens, we're able to interpolate on a token stream using simple SPairs,
like I always hoped (and reverted back to in the previous commit).

Oh, and what about that desugaring pass?  There's the issue of how to
represent such a thing in the type system---ideally we'd know statically
that desugaring always lowers into a more primitive NIR that reduces the
mapping that needs to be done to AIR.  But that adds complexity, as
mentioned above.  The alternative is to just use the templat system, as I
originally wanted to, and resolve shortcomings by augmenting the template
system to be able to handle it.  That not only keeps NIR and the compiler
much simpler, but exposes more powerful tools to developers via TAME's
metalanguage, if such a thing is appropriate.

Anyway, this creates a system that's far more intuitive, and far
simpler.  It does kick the can to AIR, but that's okay, since it's also
better positioned to deal with it.

Everything I wrote above is a thought dump and has not been proof-read, so
good luck!  And lets hope this finally works out...it's actually feeling
good this time.  The journey was necessary to discover and justify what came
out of it---everything I'm stripping away was like a cocoon, and within it
is a more beautiful and more elegant TAME.

DEV-13346
main
Mike Gerwitz 2022-11-28 13:35:10 -05:00
parent 76beb117f9
commit 6d39474127
7 changed files with 195 additions and 431 deletions

View File

@ -37,7 +37,7 @@ use tamer::{
diagnose::{
AnnotatedSpan, Diagnostic, FsSpanResolver, Reporter, VisualReporter,
},
nir::{DesugarNir, DesugarNirError, SugaredNir, XirfToNir, XirfToNirError},
nir::{XirfToNir, XirfToNirError},
parse::{
Lower, ParseError, Parsed, ParsedObject, ParsedResult, UnknownToken,
},
@ -135,15 +135,13 @@ fn compile<R: Reporter>(
XirToXirf<64, RefinedText>,
_,
>::lower::<_, UnrecoverableError>(src, |toks| {
Lower::<XirToXirf<64, RefinedText>, XirfToNir, _>::lower(toks, |snir| {
Lower::<XirfToNir, DesugarNir, _>::lower(snir, |nir| {
nir.fold(Ok(()), |x, result| match result {
Ok(_) => x,
Err(e) => {
report_err(&e, reporter, &mut ebuf)?;
x
}
})
Lower::<XirToXirf<64, RefinedText>, XirfToNir, _>::lower(toks, |nir| {
nir.fold(Ok(()), |x, result| match result {
Ok(_) => x,
Err(e) => {
report_err(&e, reporter, &mut ebuf)?;
x
}
})
})
})?;
@ -297,7 +295,6 @@ pub enum RecoverableError {
XirParseError(ParseError<UnknownToken, xir::Error>),
XirfParseError(ParseError<XirToken, XirToXirfError>),
NirParseError(ParseError<XirfToken<RefinedText>, XirfToNirError>),
DesugarNirError(ParseError<SugaredNir, DesugarNirError>),
}
impl From<io::Error> for UnrecoverableError {
@ -338,12 +335,6 @@ impl From<ParseError<XirfToken<RefinedText>, XirfToNirError>>
}
}
impl From<ParseError<SugaredNir, DesugarNirError>> for RecoverableError {
fn from(e: ParseError<SugaredNir, DesugarNirError>) -> Self {
Self::DesugarNirError(e)
}
}
impl Display for UnrecoverableError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
@ -365,7 +356,6 @@ impl Display for RecoverableError {
Self::XirParseError(e) => Display::fmt(e, f),
Self::XirfParseError(e) => Display::fmt(e, f),
Self::NirParseError(e) => Display::fmt(e, f),
Self::DesugarNirError(e) => Display::fmt(e, f),
}
}
}
@ -387,7 +377,6 @@ impl Error for RecoverableError {
Self::XirParseError(e) => Some(e),
Self::XirfParseError(e) => Some(e),
Self::NirParseError(e) => Some(e),
Self::DesugarNirError(e) => Some(e),
}
}
}
@ -407,7 +396,6 @@ impl Diagnostic for RecoverableError {
Self::XirParseError(e) => e.describe(),
Self::XirfParseError(e) => e.describe(),
Self::NirParseError(e) => e.describe(),
Self::DesugarNirError(e) => e.describe(),
}
}
}

View File

@ -49,7 +49,7 @@
//! The entry point for NIR in the lowering pipeline is exported as
//! [`XirfToNir`].
mod desugar;
mod interp;
mod parse;
use crate::{
@ -70,25 +70,19 @@ use std::{
fmt::{Debug, Display},
};
pub use desugar::{DesugarNir, DesugarNirError};
pub use parse::{
NirParseState as XirfToNir, NirParseStateError_ as XirfToNirError,
};
use NirSymbolTy::*;
/// IR that is "near" the source code,
/// without its syntactic sugar.
/// IR that is "near" the source code.
///
/// This form contains only primitives that cannot be reasonably represented
/// by other primitives.
/// This is somewhat arbitrary and may change over time,
/// but represents a balance between the level of abstraction of the IR
/// and performance of lowering operations.
///
/// See [`SugaredNir`] for more information about the sugared form.
/// This represents the language of TAME after it has been extracted from
/// whatever document encloses it
/// (e.g. XML).
#[derive(Debug, PartialEq, Eq)]
pub enum PlainNir {
pub enum Nir {
Todo,
TplParamOpen(Plain<{ TplParamIdent }>, Plain<{ DescLiteral }>),
@ -97,9 +91,9 @@ pub enum PlainNir {
TplParamValue(Plain<{ TplParamIdent }>),
}
type Plain<const TY: NirSymbolTy> = PlainNirSymbol<TY>;
type Plain<const TY: NirSymbolTy> = NirSymbol<TY>;
impl Token for PlainNir {
impl Token for Nir {
fn ir_name() -> &'static str {
"Plain NIR"
}
@ -110,7 +104,7 @@ impl Token for PlainNir {
/// many) spans associated with a token that is most likely to be
/// associated with the identity of that token.
fn span(&self) -> Span {
use PlainNir::*;
use Nir::*;
match self {
Todo => UNKNOWN_SPAN,
@ -122,11 +116,11 @@ impl Token for PlainNir {
}
}
impl Object for PlainNir {}
impl Object for Nir {}
impl Display for PlainNir {
impl Display for Nir {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
use PlainNir::*;
use Nir::*;
match self {
Todo => write!(f, "TODO"),
@ -144,51 +138,6 @@ impl Display for PlainNir {
}
}
/// Syntactic sugar atop of [`PlainNir`].
///
/// NIR contains various syntax features that serve as mere quality-of-life
/// conveniences for users
/// ("sugar" to sweeten the experience).
/// These features do not add an expressiveness to the language,
/// and are able to be lowered into other primitives without changing
/// its meaning.
///
/// The process of lowering syntactic sugar into primitives is called
/// "desugaring" and is carried out by the [`DesugarNir`] lowering
/// operation,
/// producing [`PlainNir`].
#[derive(Debug, PartialEq, Eq)]
pub enum SugaredNir {
/// A primitive token that may have sugared values.
Todo,
}
impl Token for SugaredNir {
fn ir_name() -> &'static str {
"Sugared NIR"
}
fn span(&self) -> Span {
use SugaredNir::*;
match self {
Todo => UNKNOWN_SPAN,
}
}
}
impl Object for SugaredNir {}
impl Display for SugaredNir {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
use SugaredNir::*;
match self {
Todo => write!(f, "TODO"),
}
}
}
/// Tag representing the type of a NIR value.
///
/// NIR values originate from attributes,
@ -274,7 +223,7 @@ impl Display for NirSymbolTy {
}
}
/// A plain (desugared) ([`SymbolId`], [`Span`]) pair representing an
/// A ([`SymbolId`], [`Span`]) pair representing an
/// attribute value that may need to be interpreted within the context of
/// a template application.
///
@ -283,54 +232,13 @@ impl Display for NirSymbolTy {
/// stream,
/// which must persist in memory for a short period of time,
/// and therefore cannot be optimized away as other portions of the IR.
/// As such,
/// this does not nest enums.
///
/// For the sugared form that the user may have entered themselves,
/// see [`SugaredNirSymbol`].
#[derive(Debug, PartialEq, Eq)]
pub enum PlainNirSymbol<const TY: NirSymbolTy> {
Todo(SymbolId, Span),
}
pub struct NirSymbol<const TY: NirSymbolTy>(SymbolId, Span);
impl<const TY: NirSymbolTy> PlainNirSymbol<TY> {
pub fn span(&self) -> Span {
match self {
Self::Todo(_, span) => *span,
}
}
}
impl<const TY: NirSymbolTy> Display for PlainNirSymbol<TY> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::Todo(sym, _) => write!(
f,
"TODO plain {TY} {fmt_sym}",
fmt_sym = TtQuote::wrap(sym),
),
}
}
}
/// A ([`SymbolId`], [`Span`]) pair in an attribute value context that may
/// require desugaring.
///
/// For more information on desugaring,
/// see [`DesugarNir`].
///
/// _This object must be kept small_,
/// since it is used in objects that aggregate portions of the token
/// stream,
/// which must persist in memory for a short period of time,
/// and therefore cannot be optimized away as other portions of the IR.
#[derive(Debug, PartialEq, Eq)]
pub struct SugaredNirSymbol<const TY: NirSymbolTy>(SymbolId, Span);
impl<const TY: NirSymbolTy> Token for SugaredNirSymbol<TY> {
impl<const TY: NirSymbolTy> Token for NirSymbol<TY> {
fn ir_name() -> &'static str {
// TODO: Include type?
"Sugared NIR Symbol"
"NIR Symbol"
}
fn span(&self) -> Span {
@ -340,24 +248,35 @@ impl<const TY: NirSymbolTy> Token for SugaredNirSymbol<TY> {
}
}
impl<const TY: NirSymbolTy> Display for SugaredNirSymbol<TY> {
impl<const TY: NirSymbolTy> Display for NirSymbol<TY> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self(sym, _span) => write!(
f,
"possibly-sugared {TY} {fmt_sym}",
"{TY} {fmt_sym}",
fmt_sym = TtQuote::wrap(sym),
),
}
}
}
impl<const TY: NirSymbolTy> From<(SymbolId, Span)> for NirSymbol<TY> {
fn from((val, span): (SymbolId, Span)) -> Self {
Self(val, span)
}
}
impl<const TY: NirSymbolTy> From<Attr> for NirSymbol<TY> {
fn from(attr: Attr) -> Self {
match attr {
Attr(_, val, AttrSpan(_, vspan)) => (val, vspan).into(),
}
}
}
// Force developer to be conscious of any changes in size;
// see `SugaredNirSymbol` docs for more information.
assert_eq_size!(
SugaredNirSymbol<{ NirSymbolTy::AnyIdent }>,
(SymbolId, Span)
);
// see `NirSymbol` docs for more information.
assert_eq_size!(NirSymbol<{ NirSymbolTy::AnyIdent }>, (SymbolId, Span));
#[derive(Debug, PartialEq, Eq)]
pub enum PkgType {
@ -370,20 +289,6 @@ pub enum PkgType {
Mod,
}
impl<const TY: NirSymbolTy> From<(SymbolId, Span)> for SugaredNirSymbol<TY> {
fn from((val, span): (SymbolId, Span)) -> Self {
Self(val, span)
}
}
impl<const TY: NirSymbolTy> From<Attr> for SugaredNirSymbol<TY> {
fn from(attr: Attr) -> Self {
match attr {
Attr(_, val, AttrSpan(_, vspan)) => (val, vspan).into(),
}
}
}
#[derive(Debug, PartialEq, Eq)]
pub struct Literal<const S: SymbolId>;

View File

@ -1,90 +0,0 @@
// Normalized (desugared) IR that is "near" the source code
//
// Copyright (C) 2014-2022 Ryan Specialty Group, LLC.
//
// This file is part of TAME.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//! Desugaring of [`SugaredNir`] into the normalized [`PlainNir`] form.
//!
//! For more information on the flavors of NIR,
//! see [the parent module](super).
mod interp;
use super::{PlainNir, SugaredNir};
use crate::{
diagnose::{AnnotatedSpan, Diagnostic},
parse::{prelude::*, NoContext},
};
use std::{error::Error, fmt::Display};
#[derive(Debug, PartialEq, Eq, Default)]
pub enum DesugarNir {
#[default]
Ready,
}
impl Display for DesugarNir {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::Ready => write!(f, "ready for next token"),
}
}
}
impl ParseState for DesugarNir {
type Token = SugaredNir;
type Object = PlainNir;
type Error = DesugarNirError;
fn parse_token(
self,
tok: Self::Token,
_: NoContext,
) -> TransitionResult<Self::Super> {
use SugaredNir::*;
match tok {
Todo => Transition(self).ok(PlainNir::Todo),
}
}
fn is_accepting(&self, _: &Self::Context) -> bool {
self == &Self::Ready
}
}
#[derive(Debug, PartialEq)]
pub enum DesugarNirError {}
impl Display for DesugarNirError {
fn fmt(&self, _f: &mut std::fmt::Formatter) -> std::fmt::Result {
// No errors yet.
Ok(())
}
}
impl Error for DesugarNirError {}
impl Diagnostic for DesugarNirError {
fn describe(&self) -> Vec<AnnotatedSpan> {
// No errors yet.
vec![]
}
}
#[cfg(test)]
mod test;

View File

@ -1,36 +0,0 @@
// Tests for NIR desugaring
//
// Copyright (C) 2014-2022 Ryan Specialty Group, LLC.
//
// This file is part of TAME.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
use super::*;
use crate::parse::Parsed;
type Sut = DesugarNir;
// Given the simplicity,
// this just really ensures that the parser terminates.
#[test]
fn maps_plain_nir_todo() {
let toks = vec![SugaredNir::Todo];
use Parsed::*;
assert_eq!(
Ok(vec![Object(PlainNir::Todo)]),
Sut::parse(toks.into_iter()).collect(),
);
}

View File

@ -37,7 +37,7 @@
//! ```
//!
//! The string `foo{@bar@}baz` is the interpolation specification.
//! This ends up desugaring into the [`PlainNir`] equivalent of this:
//! This ends up desugaring into the [`Nir`] equivalent of this:
//!
//! ```xml
//! <param name="@___dsgr_01@"
@ -59,7 +59,7 @@
//! This desugaring process does not check for this context;
//! errors would occur later on in the lowering pipeline.
//!
//! Since interpolation desugars into [`PlainNir`],
//! Since interpolation desugars into [`Nir`],
//! and not source XML,
//! generated `param`s will be automatically be interpreted downstream in
//! the lowering pipeline as if they were hoisted to the template
@ -99,7 +99,7 @@
use memchr::memchr;
use super::super::{PlainNir, PlainNirSymbol};
use super::{Nir, NirSymbol};
use crate::{
diagnose::{AnnotatedSpan, Diagnostic},
fmt::{DisplayWrapper, TtQuote},
@ -209,7 +209,7 @@ impl Display for InterpState {
impl ParseState for InterpState {
type Token = SPair;
type Object = Expansion<SPair, PlainNir>;
type Object = Expansion<SPair, Nir>;
type Error = InterpError;
fn parse_token(
@ -267,9 +267,8 @@ impl ParseState for InterpState {
let literal = s[offset..end].intern();
let span_text = span.slice(offset, rel_pos);
let text = PlainNir::TplParamText(
PlainNirSymbol::Todo(literal, span_text),
);
let text =
Nir::TplParamText(NirSymbol(literal, span_text));
Transition(ParseInterpAt(s, gen_param, end + 1))
.ok(Expanded(text))
@ -281,9 +280,8 @@ impl ParseState for InterpState {
let literal = s[offset..].intern();
let span_text = span.slice(offset, s.len() - offset);
let text = PlainNir::TplParamText(
PlainNirSymbol::Todo(literal, span_text),
);
let text =
Nir::TplParamText(NirSymbol(literal, span_text));
// Keep in the current state but update the offset;
// we'll complete parsing next pass.
@ -318,9 +316,8 @@ impl ParseState for InterpState {
// it is also the length of the value string.
let span_value = span.slice(offset, rel_pos);
let param_value = PlainNir::TplParamValue(
PlainNirSymbol::Todo(value, span_value),
);
let param_value =
Nir::TplParamValue(NirSymbol(value, span_value));
// Continue parsing one character past the '}',
// back in a literal context.
@ -387,9 +384,9 @@ impl InterpState {
let GenIdentSymbolId(gen_param_sym) = gen_param;
let open = PlainNir::TplParamOpen(
PlainNirSymbol::Todo(gen_param_sym, span),
PlainNirSymbol::Todo(gen_desc, span),
let open = Nir::TplParamOpen(
NirSymbol(gen_param_sym, span),
NirSymbol(gen_desc, span),
);
// Begin parsing in a _literal_ context,
@ -410,7 +407,7 @@ impl InterpState {
sym: SymbolId,
span: Span,
) -> TransitionResult<Self> {
let close = PlainNir::TplParamClose(span);
let close = Nir::TplParamClose(span);
// We have one last thing to do before we're complete,
// which is to perform the final replacement of the original

View File

@ -19,7 +19,7 @@
use super::*;
use crate::{
nir::PlainNirSymbol,
nir::NirSymbol,
parse::Parsed,
span::dummy::{DUMMY_CONTEXT as DC, *},
sym::GlobalSymbolResolve,
@ -73,9 +73,9 @@ fn desugars_literal_with_ending_var() {
let toks = vec![given_sym];
let GenIdentSymbolId(expect_name) = gen_tpl_param_ident_at_offset(a);
let expect_dfn = PlainNirSymbol::Todo(expect_name.into(), a);
let expect_text = PlainNirSymbol::Todo("foo".into(), b);
let expect_param = PlainNirSymbol::Todo("@bar@".into(), c);
let expect_dfn = NirSymbol(expect_name.into(), a);
let expect_text = NirSymbol("foo".into(), b);
let expect_param = NirSymbol("@bar@".into(), c);
let mut sut = Sut::parse(toks.into_iter());
@ -87,9 +87,9 @@ fn desugars_literal_with_ending_var() {
// helpful information to a human reader.
assert_matches!(
sut.next(),
Some(Ok(Object(Expanded(PlainNir::TplParamOpen(
Some(Ok(Object(Expanded(Nir::TplParamOpen(
dfn,
PlainNirSymbol::Todo(desc_str, desc_span)
NirSymbol(desc_str, desc_span)
))))) if dfn == expect_dfn
&& desc_str.lookup_str().contains(given_val)
&& desc_span == a
@ -100,21 +100,21 @@ fn desugars_literal_with_ending_var() {
// specification string.
assert_eq!(
sut.next(),
Some(Ok(Object(Expanded(PlainNir::TplParamText(expect_text)))))
Some(Ok(Object(Expanded(Nir::TplParamText(expect_text)))))
);
// This is the actual metavariable reference,
// pulled out of the interpolated portion of the given value.
assert_eq!(
sut.next(),
Some(Ok(Object(Expanded(PlainNir::TplParamValue(expect_param))))),
Some(Ok(Object(Expanded(Nir::TplParamValue(expect_param))))),
);
// This is an object generated from user input,
// so the closing span has to identify what were generated from.
assert_eq!(
sut.next(),
Some(Ok(Object(Expanded(PlainNir::TplParamClose(a)))))
Some(Ok(Object(Expanded(Nir::TplParamClose(a)))))
);
// Finally,
@ -152,9 +152,9 @@ fn desugars_var_with_ending_literal() {
let toks = vec![given_sym];
let GenIdentSymbolId(expect_name) = gen_tpl_param_ident_at_offset(a);
let expect_dfn = PlainNirSymbol::Todo(expect_name.into(), a);
let expect_param = PlainNirSymbol::Todo("@foo@".into(), b);
let expect_text = PlainNirSymbol::Todo("bar".into(), c);
let expect_dfn = NirSymbol(expect_name.into(), a);
let expect_param = NirSymbol("@foo@".into(), b);
let expect_text = NirSymbol("bar".into(), c);
let mut sut = Sut::parse(toks.into_iter());
@ -164,9 +164,9 @@ fn desugars_var_with_ending_literal() {
assert_matches!(
sut.next(),
Some(Ok(Object(Expanded(PlainNir::TplParamOpen(
Some(Ok(Object(Expanded(Nir::TplParamOpen(
dfn,
PlainNirSymbol::Todo(desc_str, desc_span)
NirSymbol(desc_str, desc_span)
))))) if dfn == expect_dfn
&& desc_str.lookup_str().contains(given_val)
&& desc_span == a
@ -174,17 +174,17 @@ fn desugars_var_with_ending_literal() {
assert_eq!(
sut.next(),
Some(Ok(Object(Expanded(PlainNir::TplParamValue(expect_param))))),
Some(Ok(Object(Expanded(Nir::TplParamValue(expect_param))))),
);
assert_eq!(
sut.next(),
Some(Ok(Object(Expanded(PlainNir::TplParamText(expect_text)))))
Some(Ok(Object(Expanded(Nir::TplParamText(expect_text)))))
);
assert_eq!(
sut.next(),
Some(Ok(Object(Expanded(PlainNir::TplParamClose(a)))))
Some(Ok(Object(Expanded(Nir::TplParamClose(a)))))
);
assert_matches!(
@ -219,11 +219,11 @@ fn desugars_many_vars_and_literals() {
let toks = vec![given_sym];
let GenIdentSymbolId(expect_name) = gen_tpl_param_ident_at_offset(a);
let expect_dfn = PlainNirSymbol::Todo(expect_name.into(), a);
let expect_text1 = PlainNirSymbol::Todo("foo".into(), b);
let expect_param1 = PlainNirSymbol::Todo("@bar@".into(), c);
let expect_text2 = PlainNirSymbol::Todo("baz".into(), d);
let expect_param2 = PlainNirSymbol::Todo("@quux@".into(), e);
let expect_dfn = NirSymbol(expect_name.into(), a);
let expect_text1 = NirSymbol("foo".into(), b);
let expect_param1 = NirSymbol("@bar@".into(), c);
let expect_text2 = NirSymbol("baz".into(), d);
let expect_param2 = NirSymbol("@quux@".into(), e);
let mut sut = Sut::parse(toks.into_iter());
@ -233,9 +233,9 @@ fn desugars_many_vars_and_literals() {
assert_matches!(
sut.next(),
Some(Ok(Object(Expanded(PlainNir::TplParamOpen(
Some(Ok(Object(Expanded(Nir::TplParamOpen(
dfn,
PlainNirSymbol::Todo(desc_str, desc_span)
NirSymbol(desc_str, desc_span)
))))) if dfn == expect_dfn
&& desc_str.lookup_str().contains(given_val)
&& desc_span == a
@ -244,21 +244,21 @@ fn desugars_many_vars_and_literals() {
assert_eq!(
Ok(vec![
// These two are the as previous tests.
Object(Expanded(PlainNir::TplParamText(expect_text1))),
Object(Expanded(PlainNir::TplParamValue(expect_param1))),
Object(Expanded(Nir::TplParamText(expect_text1))),
Object(Expanded(Nir::TplParamValue(expect_param1))),
// This pair repeats literals and vars further into the pattern
// to ensure that the parser is able to handle returning to
// previous states and is able to handle inputs at different
// offsets.
Object(Expanded(PlainNir::TplParamText(expect_text2))),
Object(Expanded(PlainNir::TplParamValue(expect_param2))),
Object(Expanded(Nir::TplParamText(expect_text2))),
Object(Expanded(Nir::TplParamValue(expect_param2))),
]),
sut.by_ref().take(4).collect(),
);
assert_eq!(
sut.next(),
Some(Ok(Object(Expanded(PlainNir::TplParamClose(a)))))
Some(Ok(Object(Expanded(Nir::TplParamClose(a)))))
);
assert_matches!(
@ -290,10 +290,10 @@ fn desugars_adjacent_interpolated_vars() {
let toks = vec![given_sym];
let GenIdentSymbolId(expect_name) = gen_tpl_param_ident_at_offset(a);
let expect_dfn = PlainNirSymbol::Todo(expect_name.into(), a);
let expect_param1 = PlainNirSymbol::Todo("@foo@".into(), b);
let expect_param2 = PlainNirSymbol::Todo("@bar@".into(), c);
let expect_param3 = PlainNirSymbol::Todo("@baz@".into(), d);
let expect_dfn = NirSymbol(expect_name.into(), a);
let expect_param1 = NirSymbol("@foo@".into(), b);
let expect_param2 = NirSymbol("@bar@".into(), c);
let expect_param3 = NirSymbol("@baz@".into(), d);
let mut sut = Sut::parse(toks.into_iter());
@ -303,9 +303,9 @@ fn desugars_adjacent_interpolated_vars() {
assert_matches!(
sut.next(),
Some(Ok(Object(Expanded(PlainNir::TplParamOpen(
Some(Ok(Object(Expanded(Nir::TplParamOpen(
dfn,
PlainNirSymbol::Todo(desc_str, desc_span)
NirSymbol(desc_str, desc_span)
))))) if dfn == expect_dfn
&& desc_str.lookup_str().contains(given_val)
&& desc_span == a
@ -314,16 +314,16 @@ fn desugars_adjacent_interpolated_vars() {
// These are the three adjacent vars.
assert_eq!(
Ok(vec![
Object(Expanded(PlainNir::TplParamValue(expect_param1))),
Object(Expanded(PlainNir::TplParamValue(expect_param2))),
Object(Expanded(PlainNir::TplParamValue(expect_param3))),
Object(Expanded(Nir::TplParamValue(expect_param1))),
Object(Expanded(Nir::TplParamValue(expect_param2))),
Object(Expanded(Nir::TplParamValue(expect_param3))),
]),
sut.by_ref().take(3).collect(),
);
assert_eq!(
sut.next(),
Some(Ok(Object(Expanded(PlainNir::TplParamClose(a)))))
Some(Ok(Object(Expanded(Nir::TplParamClose(a)))))
);
assert_matches!(

View File

@ -112,10 +112,10 @@ use crate::{
},
};
type N<const TY: NirSymbolTy> = SugaredNirSymbol<TY>;
type N<const TY: NirSymbolTy> = NirSymbol<TY>;
ele_parse! {
/// Parser lowering [XIR](crate::xir) into [`SugaredNir`].
/// Parser lowering [XIR](crate::xir) into [`Nir`].
///
/// TAME's grammar is embedded within XML.
/// The outer XML document has its own grammar,
@ -157,13 +157,13 @@ ele_parse! {
pub enum NirParseState;
type AttrValueError = NirAttrParseError;
type Object = SugaredNir;
type Object = Nir;
// Text and template expressions may appear at any point within the
// program;
// see [`NirParseState`] for more information.
[super] {
[text](_sym, _span) => SugaredNir::Todo,
[text](_sym, _span) => Nir::Todo,
TplKw
};
@ -205,7 +205,7 @@ ele_parse! {
// TODO: Is this still needed?
// TODO: PkgName type
_name: (QN_NAME) => N<{PkgPath}>,
} => SugaredNir::Todo,
} => Nir::Todo,
ImportStmt,
PkgBodyStmt,
@ -238,7 +238,7 @@ ele_parse! {
// TODO: Can this go away now?
_name: (QN_NAME?) => Option<N<{PkgPath}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
ImportStmt,
PkgBodyStmt,
@ -252,7 +252,7 @@ ele_parse! {
@ {
_pkg: (QN_PACKAGE) => N<{PkgPath}>,
_export: (QN_EXPORT?) => Option<N<{BooleanLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
};
/// A statement that is accepted within the body of a package.
@ -300,7 +300,7 @@ ele_parse! {
_dim: (QN_DIM) => N<{NumLiteral}>,
_parent: (QN_PARENT?) => Option<N<{AnyIdent}>>,
_yields: (QN_YIELDS?) => Option<N<{ValueIdent}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
};
/// Define an input parameter accepting data from an external system.
@ -316,7 +316,7 @@ ele_parse! {
_set: (QN_SET?) => Option<N<{Dim}>>,
_default: (QN_DEFAULT?) => Option<N<{ParamDefault}>>,
_sym: (QN_SYM?) => Option<N<{TexMathLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
};
/// Associate static data with an identifier.
@ -341,7 +341,7 @@ ele_parse! {
_sym: (QN_SYM?) => Option<N<{TexMathLiteral}>>,
// TODO: Misnomer
_set: (QN_SET?) => Option<N<{Dim}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
ConstStmtBody,
};
@ -361,7 +361,7 @@ ele_parse! {
ConstMatrixRow := QN_SET {
@ {
_desc: (QN_DESC) => N<{DescLiteral}>,
} => SugaredNir::Todo,
} => Nir::Todo,
ConstVectorItem,
};
@ -371,7 +371,7 @@ ele_parse! {
@ {
_value: (QN_VALUE) => N<{NumLiteral}>,
_desc: (QN_DESC) => N<{DescLiteral}>,
} => SugaredNir::Todo,
} => Nir::Todo,
};
/// Define a classification and associate it with an identifier.
@ -387,7 +387,7 @@ ele_parse! {
_yields: (QN_YIELDS?) => Option<N<{ValueIdent}>>,
_sym: (QN_SYM?) => Option<N<{TexMathLiteral}>>,
_terminate: (QN_TERMINATE?) => Option<N<{BooleanLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
LogExpr,
};
@ -414,7 +414,7 @@ ele_parse! {
// TODO: We'll have private-by-default later.
// This is a kludge.
_local: (QN_LOCAL?) => Option<N<{BooleanLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
CalcExpr,
};
@ -434,7 +434,7 @@ ele_parse! {
_yields: (QN_YIELDS?) => Option<N<{ValueIdent}>>,
_sym: (QN_SYM?) => Option<N<{TexMathLiteral}>>,
_gensym: (QN_GENSYM?) => Option<N<{TexMathLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
CalcExpr,
};
@ -445,7 +445,7 @@ ele_parse! {
_name: (QN_NAME) => N<{TypeIdent}>,
_desc: (QN_DESC) => N<{DescLiteral}>,
_sym: (QN_SYM?) => Option<N<{TexMathLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
InnerTypedefStmt,
};
@ -458,7 +458,7 @@ ele_parse! {
/// This is used for primitives and allows for core types to be exposed
/// to the user.
BaseTypeStmt := QN_BASE_TYPE {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
};
/// Define an enumerated type.
@ -468,7 +468,7 @@ ele_parse! {
EnumStmt := QN_ENUM {
@ {
_ty: (QN_TYPE) => N<{TypeIdent}>,
} => SugaredNir::Todo,
} => Nir::Todo,
ItemEnumStmt,
};
@ -480,13 +480,13 @@ ele_parse! {
_name: (QN_NAME) => N<{ConstIdent}>,
_value: (QN_VALUE) => N<{NumLiteral}>,
_desc: (QN_DESC) => N<{DescLiteral}>,
} => SugaredNir::Todo,
} => Nir::Todo,
};
/// Define a type whose domain is the union of the domains of multiple
/// other types.
UnionStmt := QN_UNION {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
TypedefStmt,
};
@ -501,7 +501,7 @@ ele_parse! {
/// This is being replaced with the `__yield__` template in `core`
/// (this statement predates the template system in TAME).
YieldStmt := QN_YIELD {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
CalcExpr,
};
@ -523,7 +523,7 @@ ele_parse! {
SectionStmt := QN_SECTION {
@ {
_title: (QN_TITLE) => N<{Title}>,
} => SugaredNir::Todo,
} => Nir::Todo,
PkgBodyStmt,
};
@ -534,7 +534,7 @@ ele_parse! {
_name: (QN_NAME) => N<{FuncIdent}>,
_desc: (QN_DESC) => N<{DescLiteral}>,
_sym: (QN_SYM?) => Option<N<{TexMathLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
FunctionParamStmt,
CalcExpr,
@ -549,7 +549,7 @@ ele_parse! {
// _TODO: This is a misnomer.
_set: (QN_SET?) => Option<N<{Dim}>>,
_desc: (QN_DESC) => N<{DescLiteral}>,
} => SugaredNir::Todo,
} => Nir::Todo,
};
@ -575,7 +575,7 @@ ele_parse! {
_value: (QN_VALUE?) => Option<N<{ValueIdent}>>,
_index: (QN_INDEX?) => Option<N<{ValueIdent}>>,
_anyof: (QN_ANY_OF?) => Option<N<{TypeIdent}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
CalcPredExpr,
};
@ -585,7 +585,7 @@ ele_parse! {
/// This represents an expression that matches when _any_ of its inner
/// [`LogExpr`] expressions match.
AnyExpr := QN_ANY {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
LogExpr,
};
@ -595,7 +595,7 @@ ele_parse! {
/// This represents an expression that matches when _all_ of its inner
/// [`LogExpr`] expressions match.
AllExpr := QN_ALL {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
LogExpr,
};
@ -662,7 +662,7 @@ ele_parse! {
_label: (QN_LABEL?) => Option<N<{DescLiteral}>>,
_sym: (QN_SYM?) => Option<N<{TexMathLiteral}>>,
_dim: (QN_DIM?) => Option<N<{Dim}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
WhenExpr,
CalcExpr,
@ -684,7 +684,7 @@ ele_parse! {
_dot: (QN_DOT?) => Option<N<{BooleanLiteral}>>,
_sym: (QN_SYM?) => Option<N<{TexMathLiteral}>>,
_dim: (QN_DIM?) => Option<N<{Dim}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
WhenExpr,
CalcExpr,
@ -700,7 +700,7 @@ ele_parse! {
QuotientExpr := QN_C_QUOTIENT {
@ {
_label: (QN_LABEL?) => Option<N<{DescLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
CalcExpr,
};
@ -716,7 +716,7 @@ ele_parse! {
/// (respectively),
/// but TAMER will be relaxing that restriction.
ExptExpr := QN_C_EXPT {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
CalcExpr,
};
@ -731,7 +731,7 @@ ele_parse! {
_name: (QN_NAME) => N<{ValueIdent}>,
_index: (QN_INDEX?) => Option<N<{ValueIdent}>>,
_label: (QN_LABEL?) => Option<N<{DescLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
IndexExpr,
WhenExpr,
@ -747,7 +747,7 @@ ele_parse! {
IndexExpr := QN_C_INDEX {
@ {
_label: (QN_LABEL?) => Option<N<{DescLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
CalcExpr,
};
@ -766,7 +766,7 @@ ele_parse! {
_desc: (QN_DESC?) => Option<N<{DescLiteral}>>,
// _TODO: deprecate?
_ty: (QN_TYPE?) => Option<N<{TypeIdent}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
WhenExpr,
};
@ -775,7 +775,7 @@ ele_parse! {
CeilExpr := QN_C_CEIL {
@ {
_label: (QN_LABEL?) => Option<N<{DescLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
CalcExpr,
};
@ -783,7 +783,7 @@ ele_parse! {
FloorExpr := QN_C_FLOOR {
@ {
_label: (QN_LABEL?) => Option<N<{DescLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
CalcExpr,
};
@ -803,7 +803,7 @@ ele_parse! {
CasesExpr := QN_C_CASES {
@ {
_label: (QN_LABEL?) => Option<N<{DescLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
CaseExpr,
OtherwiseExpr,
@ -823,7 +823,7 @@ ele_parse! {
CaseExpr := QN_C_CASE {
@ {
_label: (QN_LABEL?) => Option<N<{DescLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
WhenExpr,
CalcExpr,
@ -846,7 +846,7 @@ ele_parse! {
OtherwiseExpr := QN_C_OTHERWISE {
@ {
_label: (QN_LABEL?) => Option<N<{DescLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
CalcExpr,
};
@ -857,7 +857,7 @@ ele_parse! {
/// which are vectors of vectors.
/// It is not defined for scalars.
LengthOfExpr := QN_C_LENGTH_OF {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
CalcExpr,
};
@ -871,7 +871,7 @@ ele_parse! {
/// The result of the let expression is the result of the inner
/// [`CalcExpr`].
LetExpr := QN_C_LET {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
LetValues,
CalcExpr,
};
@ -881,7 +881,7 @@ ele_parse! {
///
/// See [`LetExpr`] for more information.
LetValues := QN_C_VALUES {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
LetValue,
};
@ -898,7 +898,7 @@ ele_parse! {
// Misnomer
_set: (QN_SET?) => Option<N<{Dim}>>,
_desc: (QN_DESC?) => Option<N<{DescLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
CalcExpr,
};
@ -908,7 +908,7 @@ ele_parse! {
VectorExpr := QN_C_VECTOR {
@ {
_label: (QN_LABEL?) => Option<N<{DescLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
CalcExpr,
};
@ -925,9 +925,9 @@ ele_parse! {
/// `<`[`c:arg`](QN_C_ARG)` name="α"><`[`c:value-of`](QN_C_VALUE_OF)
/// `name="x" /></c:arg>`.
ApplyExpr := QN_C_APPLY {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
[attr](_attr) => SugaredNir::Todo,
[attr](_attr) => Nir::Todo,
ApplyArg,
};
@ -940,7 +940,7 @@ ele_parse! {
ApplyArg := QN_C_ARG {
@ {
_name: (QN_NAME) => N<{ParamIdent}>,
} => SugaredNir::Todo,
} => Nir::Todo,
CalcExpr,
};
@ -955,9 +955,9 @@ ele_parse! {
/// allowing for concise recursion in terms of only what has changed
/// in that recursive step.
RecurseExpr := QN_C_RECURSE {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
[attr](_attr) => SugaredNir::Todo,
[attr](_attr) => Nir::Todo,
ApplyArg,
};
@ -968,7 +968,7 @@ ele_parse! {
/// This terminology originates from Lisp.
/// It is equivalent to an `unshift` operation.
ConsExpr := QN_C_CONS {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
CalcExpr,
};
@ -978,7 +978,7 @@ ele_parse! {
CarExpr := QN_C_CAR {
@ {
_label: (QN_LABEL?) => Option<N<{DescLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
CalcExpr,
};
@ -990,7 +990,7 @@ ele_parse! {
CdrExpr := QN_C_CDR {
@ {
_label: (QN_LABEL?) => Option<N<{DescLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
CalcExpr,
};
@ -1012,7 +1012,7 @@ ele_parse! {
_name: (QN_NAME) => N<{ValueIdent}>,
_index: (QN_INDEX?) => Option<N<{ValueIdent}>>,
_value: (QN_VALUE?) => Option<N<{ValueIdent}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
CalcPredExpr,
};
@ -1032,37 +1032,37 @@ ele_parse! {
/// Equality predicate (=).
EqCalcPredExpr := QN_C_EQ {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
CalcExpr,
};
/// Non-equality predicate (≠).
NeCalcPredExpr := QN_C_NE {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
CalcExpr,
};
/// Less-than predicate (<).
LtCalcPredExpr := QN_C_LT {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
CalcExpr,
};
/// Greater-than predicate (>).
GtCalcPredExpr := QN_C_GT {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
CalcExpr,
};
/// Less-than or equality predicate (≤).
LteCalcPredExpr := QN_C_LTE {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
CalcExpr,
};
/// Greater-than or equality predicate (≥).
GteCalcPredExpr := QN_C_GTE {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
CalcExpr,
};
@ -1089,7 +1089,7 @@ ele_parse! {
_xmlns: (QN_XMLNS) => Literal<URI_LV_PROGRAM_MAP>,
_xmlnslv: (QN_XMLNS_LV) => Literal<URI_LV_RATER>,
_src: (QN_SRC) => N<{PkgPath}>,
} => SugaredNir::Todo,
} => Nir::Todo,
MapPkgImportStmt,
MapImportStmt,
@ -1107,7 +1107,7 @@ ele_parse! {
@ {
_xmlns: (QN_XMLNS) => Literal<URI_LV_PROGRAM_MAP>,
_xmlnslv: (QN_XMLNS_LV) => Literal<URI_LV_RATER>,
} => SugaredNir::Todo,
} => Nir::Todo,
MapPkgImportStmt,
MapImportStmt,
@ -1123,7 +1123,7 @@ ele_parse! {
@ {
_package: (QN_PACKAGE) => N<{PkgPath}>,
_export: (QN_EXPORT?) => Option<N<{BooleanLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
};
/// Import a map package.
@ -1134,7 +1134,7 @@ ele_parse! {
MapImportStmt := QN_IMPORT {
@ {
_path: (QN_PATH) => N<{PkgPath}>,
} => SugaredNir::Todo,
} => Nir::Todo,
};
/// Define the value of a key in the destination.
@ -1150,7 +1150,7 @@ ele_parse! {
_scalar: (QN_SCALAR?) => Option<N<{BooleanLiteral}>>,
_override: (QN_OVERRIDE?) => Option<N<{BooleanLiteral}>>,
_novalidate: (QN_NOVALIDATE?) => Option<N<{BooleanLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
};
/// Map a value into a key of the destination.
@ -1169,7 +1169,7 @@ ele_parse! {
_scalar: (QN_SCALAR?) => Option<N<{BooleanLiteral}>>,
_override: (QN_OVERRIDE?) => Option<N<{BooleanLiteral}>>,
_novalidate: (QN_NOVALIDATE?) => Option<N<{BooleanLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
MapStmtBody,
};
@ -1184,7 +1184,7 @@ ele_parse! {
_default: (QN_DEFAULT?) => Option<N<{NumLiteral}>>,
_scalar: (QN_SCALAR?) => Option<N<{BooleanLiteral}>>,
_novalidate: (QN_NOVALIDATE?) => Option<N<{BooleanLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
MapTranslateStmt,
};
@ -1194,7 +1194,7 @@ ele_parse! {
@ {
_key: (QN_KEY) => N<{StringLiteral}>,
_value: (QN_VALUE) => N<{NumLiteral}>,
} => SugaredNir::Todo,
} => Nir::Todo,
};
/// Yield a vector of values where each item corresponds to the
@ -1204,7 +1204,7 @@ ele_parse! {
/// since the result is a vector,
/// not a set.
MapSetStmt := QN_SET {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
MapSetBody,
};
@ -1216,7 +1216,7 @@ ele_parse! {
MapConstStmt := QN_CONST {
@ {
_value: (QN_VALUE) => N<{StringLiteral}>,
} => SugaredNir::Todo,
} => Nir::Todo,
};
/// Transform a value using some function.
@ -1228,7 +1228,7 @@ ele_parse! {
MapTransformStmt := QN_TRANSFORM {
@ {
_method: (QN_METHOD) => N<{MapTransformLiteral}>,
} => SugaredNir::Todo,
} => Nir::Todo,
MapStmtBody,
};
@ -1260,7 +1260,7 @@ ele_parse! {
_name: (QN_NAME) => N<{PkgPath}>,
_pkg: (QN_PACKAGE) => N<{PkgPath}>,
} => SugaredNir::Todo,
} => Nir::Todo,
ExpandFunctionStmt,
DisplayStmt,
@ -1277,7 +1277,7 @@ ele_parse! {
ExpandFunctionStmt := QN_EXPAND_FUNCTION {
@ {
_name: (QN_NAME) => N<{FuncIdent}>,
} => SugaredNir::Todo,
} => Nir::Todo,
};
/// Render a simplified, human-readable display of the calculation,
@ -1285,7 +1285,7 @@ ele_parse! {
DisplayStmt := QN_DISPLAY {
@ {
_name: (QN_NAME) => N<{ValueIdent}>,
} => SugaredNir::Todo,
} => Nir::Todo,
};
@ -1378,7 +1378,7 @@ ele_parse! {
@ {
_name: (QN_NAME) => N<{TplIdent}>,
_desc: (QN_DESC) => N<{DescLiteral}>,
} => SugaredNir::Todo,
} => Nir::Todo,
TplHeading,
AnyStmtOrExpr,
@ -1403,7 +1403,7 @@ ele_parse! {
@ {
_name: (QN_NAME) => N<{TplParamIdent}>,
_desc: (QN_DESC) => N<{DescLiteral}>,
} => SugaredNir::Todo,
} => Nir::Todo,
TplParamDefault,
};
@ -1436,7 +1436,7 @@ ele_parse! {
TplText := QN_TEXT {
@ {
_unique: (QN_UNIQUE?) => Option<N<{BooleanLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
};
/// Default the param to the value of another template param,
@ -1459,7 +1459,7 @@ ele_parse! {
_rmunderscore: (QN_RMUNDERSCORE?) => Option<N<{BooleanLiteral}>>,
_identifier: (QN_IDENTIFIER?) => Option<N<{BooleanLiteral}>>,
_snake: (QN_SNAKE?) => Option<N<{BooleanLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
};
/// Inherit a default value from a metavalue.
@ -1474,7 +1474,7 @@ ele_parse! {
TplParamInherit := QN_PARAM_INHERIT {
@ {
_meta: (QN_META) => N<{TplMetaIdent}>,
} => SugaredNir::Todo,
} => Nir::Todo,
};
/// Sum a numeric value with a numeric template parameter.
@ -1485,7 +1485,7 @@ ele_parse! {
@ {
_name: (QN_NAME) => N<{TplParamIdent}>,
_value: (QN_VALUE) => N<{NumLiteral}>,
} => SugaredNir::Todo,
} => Nir::Todo,
};
/// Look up the [`@yields`](QN_YIELDS) of a [`ClassifyStmt`].
@ -1506,7 +1506,7 @@ ele_parse! {
TplParamClassToYields := QN_PARAM_CLASS_TO_YIELDS {
@ {
_name: (QN_NAME) => N<{ClassIdent}>,
} => SugaredNir::Todo,
} => Nir::Todo,
};
/// Given a numeric literal,
@ -1551,7 +1551,7 @@ ele_parse! {
@ {
_name: (QN_NAME) => N<{TypeIdent}>,
_value: (QN_VALUE) => N<{NumLiteral}>,
} => SugaredNir::Todo,
} => Nir::Todo,
};
/// Look up an attribute from the symbol table for a given identifier.
@ -1561,7 +1561,7 @@ ele_parse! {
_value: (QN_VALUE) => N<{SymbolTableKey}>,
_prefix: (QN_PREFIX?) => Option<N<{AnyIdent}>>,
_ignore_missing: (QN_IGNORE_MISSING?) => Option<N<{BooleanLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
};
/// Keywords that trigger template expansion.
@ -1604,7 +1604,7 @@ ele_parse! {
DynNode := QN_DYN_NODE {
@ {
_name: (QN_NAME) => N<{DynNodeLiteral}>,
} => SugaredNir::Todo,
} => Nir::Todo,
// But we can at least restrict it for now by ensuring that it's
// used only to contain expressions.
@ -1620,7 +1620,7 @@ ele_parse! {
/// See also [`WarningKw`] to provide a message to the user as
/// compiler output without failing compilation.
ErrorKw := QN_ERROR {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
// In addition to text that is globally permitted.
TplParamValue,
@ -1636,7 +1636,7 @@ ele_parse! {
/// you should consider using [`ErrorKw`] whenever possible to
/// ensure that problems are immediately resolved.
WarningKw := QN_WARNING {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
// In addition to text that is globally permitted.
TplParamValue,
@ -1658,7 +1658,7 @@ ele_parse! {
/// but this is still needed to support dynamic template application
/// (templates whose names are derived from other template inputs).
ApplyTemplate := QN_APPLY_TEMPLATE {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
// TODO
};
@ -1671,12 +1671,12 @@ ele_parse! {
/// template argument.
/// See [`ApplyTemplate`] for more information.
TplApplyShort := NS_T {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
// Streaming attribute parsing;
// this takes precedence over any attribute parsing above
// (which is used only for emitting the opening object).
[attr](_attr) => SugaredNir::Todo,
[attr](_attr) => Nir::Todo,
// Template bodies depend on context,
// so we have to just accept everything and defer to a future
@ -1696,7 +1696,7 @@ ele_parse! {
/// and have the unique ability to perform symbol table
/// introspection using [`InlineTemplateSymSet`].
InlineTemplate := QN_INLINE_TEMPLATE {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
InlineTemplateForEach,
AnyStmtOrExpr,
@ -1711,7 +1711,7 @@ ele_parse! {
/// each with the respective [`InlineTemplateArgs`] set as its
/// arguments.
InlineTemplateForEach := QN_FOR_EACH {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
InlineTemplateArgs,
};
@ -1728,10 +1728,10 @@ ele_parse! {
///
/// See also parent [`InlineTemplateForEach`].
InlineTemplateArgSet := QN_SET {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
// Streaming attribute parsing.
[attr](_attr) => SugaredNir::Todo,
[attr](_attr) => Nir::Todo,
// TODO: REMOVE ME
// (bug in `ele_parse!` requiring at least one NT in this
@ -1756,7 +1756,7 @@ ele_parse! {
_name_prefix: (QN_NAME_PREFIX?) => Option<N<{StringLiteral}>>,
_type: (QN_TYPE?) => Option<N<{IdentType}>>,
// TODO: Look at XSL sources for others
} => SugaredNir::Todo,
} => Nir::Todo,
};
/// Perform template expansion on each successive child node in order,
@ -1786,7 +1786,7 @@ ele_parse! {
/// The concept originates from TeX's `\expandafter`, `\edef`, and
/// related macros.
ExpandSequence := QN_EXPAND_SEQUENCE {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
AnyStmtOrExpr,
};
@ -1796,7 +1796,7 @@ ele_parse! {
/// implementation of [`ExpandSequence`];
/// see that NT for more information.
ExpandGroup := QN_EXPAND_GROUP {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
AnyStmtOrExpr,
};
@ -1806,7 +1806,7 @@ ele_parse! {
/// template system from expanding its body beyond a certain point,
/// which is sometimes needed for template-producing templates.
ExpandBarrier := QN_EXPAND_BARRIER {
@ {} => SugaredNir::Todo,
@ {} => Nir::Todo,
AnyStmtOrExpr,
};
@ -1819,7 +1819,7 @@ ele_parse! {
TplParamCopy := QN_PARAM_COPY {
@ {
_name: (QN_NAME) => N<{TplParamIdent}>,
} => SugaredNir::Todo,
} => Nir::Todo,
};
/// Define a metavalue at this point in the expansion environment.
@ -1830,7 +1830,7 @@ ele_parse! {
@ {
_name: (QN_NAME) => N<{TplParamIdent}>,
_value: (QN_VALUE) => N<{StringLiteral}>,
} => SugaredNir::Todo,
} => Nir::Todo,
};
/// Conditionally expand the body if the provided predicate matches.
@ -1844,7 +1844,7 @@ ele_parse! {
_lte: (QN_LTE?) => Option<N<{NumLiteral}>>,
_prefix: (QN_PREFIX?) => Option<N<{StringLiteral}>>,
_suffix: (QN_SUFFIX?) => Option<N<{StringLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
AnyStmtOrExpr,
};
@ -1864,7 +1864,7 @@ ele_parse! {
_lte: (QN_LTE?) => Option<N<{NumLiteral}>>,
_prefix: (QN_PREFIX?) => Option<N<{StringLiteral}>>,
_suffix: (QN_SUFFIX?) => Option<N<{StringLiteral}>>,
} => SugaredNir::Todo,
} => Nir::Todo,
AnyStmtOrExpr,
};