tamer: nir::air: Dynamic configuration in place of static wip-asg-derived-xmli flag

This flag should have never been sprinkled here; it makes the system much
harder to understand.

But, this is working toward a command-line tamec option to toggle NIR
lowering on/off for various packages.

DEV-13162
main
Mike Gerwitz 2023-06-13 15:07:03 -04:00
parent 61d556c89e
commit 341af3fdaf
5 changed files with 102 additions and 46 deletions

View File

@ -43,6 +43,7 @@ use tamer::{
diagnose::{ diagnose::{
AnnotatedSpan, Diagnostic, FsSpanResolver, Reporter, VisualReporter, AnnotatedSpan, Diagnostic, FsSpanResolver, Reporter, VisualReporter,
}, },
nir::NirToAirParseType,
parse::{lowerable, FinalizeError, ParseError, Token}, parse::{lowerable, FinalizeError, ParseError, Token},
pipeline::{parse_package_xml, LowerXmliError, ParsePackageXmlError}, pipeline::{parse_package_xml, LowerXmliError, ParsePackageXmlError},
xir::{self, reader::XmlXirReader, DefaultEscaper}, xir::{self, reader::XmlXirReader, DefaultEscaper},
@ -137,11 +138,17 @@ fn compile<R: Reporter>(
} }
})); }));
#[cfg(not(feature = "wip-asg-derived-xmli"))]
let parse_type = NirToAirParseType::Noop;
#[cfg(feature = "wip-asg-derived-xmli")]
let parse_type = NirToAirParseType::LowerKnownErrorRest;
// TODO: Determine a good default capacity once we have this populated // TODO: Determine a good default capacity once we have this populated
// and can come up with some heuristics. // and can come up with some heuristics.
let (air_ctx,) = parse_package_xml(DefaultAsg::with_capacity(1024, 2048))( let (_, air_ctx) = parse_package_xml(
src, report_err, parse_type,
)?; DefaultAsg::with_capacity(1024, 2048),
)(src, report_err)?;
match reporter.has_errors() { match reporter.has_errors() {
false => { false => {

View File

@ -72,7 +72,7 @@ use std::{
fmt::{Debug, Display}, fmt::{Debug, Display},
}; };
pub use air::{NirToAir, NirToAirError}; pub use air::{NirToAir, NirToAirError, NirToAirParseType};
pub use interp::{InterpError, InterpState as InterpolateNir}; pub use interp::{InterpError, InterpState as InterpolateNir};
pub use parse::{ pub use parse::{
NirParseState as XirfToNir, NirParseStateError_ as XirfToNirError, NirParseState as XirfToNir, NirParseStateError_ as XirfToNirError,

View File

@ -21,22 +21,58 @@
use super::Nir; use super::Nir;
use crate::{ use crate::{
asg::air::Air, asg::{air::Air, ExprOp},
diagnose::{Annotate, Diagnostic}, diagnose::{Annotate, Diagnostic},
fmt::{DisplayWrapper, TtQuote}, fmt::{DisplayWrapper, TtQuote},
nir::{Nir::*, NirEntity::*},
parse::prelude::*, parse::prelude::*,
span::Span, span::Span,
sym::{st::raw::U_TRUE, SymbolId},
}; };
use arrayvec::ArrayVec; use arrayvec::ArrayVec;
use std::{error::Error, fmt::Display}; use std::{error::Error, fmt::Display};
// These are also used by the `test` module which imports `super`. /// Dynamic [`NirToAir`] parser configuration.
#[cfg(feature = "wip-asg-derived-xmli")] ///
use crate::{ /// This acts as a runtime feature flag while this portions of TAMER is
asg::ExprOp, /// under development.
nir::{Nir::*, NirEntity::*}, #[derive(Debug, PartialEq, Eq)]
sym::{st::raw::U_TRUE, SymbolId}, pub enum NirToAirParseType {
}; /// Discard incoming tokens instead of lowering them.
Noop,
/// Lower known tokens,
/// but produce errors for everything else that is not yet supported.
///
/// It is expected that this will fail on at least some packages;
/// this should be enabled only on packages known to compile with the
/// new system.
LowerKnownErrorRest,
}
impl Display for NirToAirParseType {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::Noop => write!(f, "discarding all tokens (noop)"),
Self::LowerKnownErrorRest => write!(
f,
"lowering only supported tokens and failing on all others"
),
}
}
}
impl From<NirToAirParseType> for (NirToAirParseType, ObjStack) {
fn from(ty: NirToAirParseType) -> Self {
(ty, Default::default())
}
}
impl From<(NirToAirParseType, ObjStack)> for NirToAirParseType {
fn from((ty, _): (NirToAirParseType, ObjStack)) -> Self {
ty
}
}
#[derive(Debug, PartialEq, Eq, Default)] #[derive(Debug, PartialEq, Eq, Default)]
pub enum NirToAir { pub enum NirToAir {
@ -78,36 +114,28 @@ type ObjStack = ArrayVec<Air, 2>;
/// The symbol to use when lexically expanding shorthand notations to /// The symbol to use when lexically expanding shorthand notations to
/// compare against values of `1`. /// compare against values of `1`.
#[cfg(feature = "wip-asg-derived-xmli")]
pub const SYM_TRUE: SymbolId = U_TRUE; pub const SYM_TRUE: SymbolId = U_TRUE;
impl ParseState for NirToAir { impl ParseState for NirToAir {
type Token = Nir; type Token = Nir;
type Object = Air; type Object = Air;
type Error = NirToAirError; type Error = NirToAirError;
type Context = ObjStack; type Context = (NirToAirParseType, ObjStack);
type PubContext = NirToAirParseType;
#[cfg(not(feature = "wip-asg-derived-xmli"))]
fn parse_token( fn parse_token(
self, self,
tok: Self::Token, tok: Self::Token,
_queue: &mut Self::Context, (parse_type, stack): &mut Self::Context,
) -> TransitionResult<Self::Super> {
use NirToAir::*;
let _ = tok; // prevent `unused_variables` warning
Transition(Ready).ok(Air::Todo(crate::span::UNKNOWN_SPAN))
}
#[cfg(feature = "wip-asg-derived-xmli")]
fn parse_token(
self,
tok: Self::Token,
stack: &mut Self::Context,
) -> TransitionResult<Self::Super> { ) -> TransitionResult<Self::Super> {
use NirToAir::*; use NirToAir::*;
use NirToAirError::*; use NirToAirError::*;
match parse_type {
NirToAirParseType::Noop => return Transition(Ready).incomplete(),
NirToAirParseType::LowerKnownErrorRest => (),
}
if let Some(obj) = stack.pop() { if let Some(obj) = stack.pop() {
return Transition(Ready).ok(obj).with_lookahead(tok); return Transition(Ready).ok(obj).with_lookahead(tok);
} }
@ -284,7 +312,7 @@ impl ParseState for NirToAir {
} }
} }
fn is_accepting(&self, stack: &Self::Context) -> bool { fn is_accepting(&self, (_, stack): &Self::Context) -> bool {
matches!(self, Self::Ready) && stack.is_empty() matches!(self, Self::Ready) && stack.is_empty()
} }
} }
@ -364,5 +392,5 @@ impl Diagnostic for NirToAirError {
} }
} }
#[cfg(all(test, feature = "wip-asg-derived-xmli"))] #[cfg(test)]
mod test; mod test;

View File

@ -18,12 +18,33 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
use super::*; use super::*;
use crate::{parse::util::SPair, span::dummy::*}; use crate::{
parse::{util::SPair, Parser},
span::dummy::*,
};
type Sut = NirToAir; type Sut = NirToAir;
use Parsed::{Incomplete, Object as O}; use Parsed::{Incomplete, Object as O};
fn sut_parse<I: Iterator<Item = Nir>>(toks: I) -> Parser<Sut, I> {
Sut::parse_with_context(
toks.into_iter(),
NirToAirParseType::LowerKnownErrorRest,
)
}
#[test]
fn ignores_input_when_parse_type_is_noop() {
let toks = vec![Open(Package, S1), Close(Package, S2)];
assert_eq!(
Ok(vec![Incomplete, Incomplete,]),
Sut::parse_with_context(toks.into_iter(), NirToAirParseType::Noop)
.collect(),
);
}
#[test] #[test]
fn package_to_pkg() { fn package_to_pkg() {
let toks = vec![Open(Package, S1), Close(Package, S2)]; let toks = vec![Open(Package, S1), Close(Package, S2)];
@ -33,7 +54,7 @@ fn package_to_pkg() {
O(Air::PkgStart(S1, SPair("/TODO".into(), S1))), O(Air::PkgStart(S1, SPair("/TODO".into(), S1))),
O(Air::PkgEnd(S2)), O(Air::PkgEnd(S2)),
]), ]),
Sut::parse(toks.into_iter()).collect(), sut_parse(toks.into_iter()).collect(),
); );
} }
@ -55,7 +76,7 @@ fn rate_to_sum_expr() {
O(Air::BindIdent(id)), O(Air::BindIdent(id)),
O(Air::ExprEnd(S3)), O(Air::ExprEnd(S3)),
]), ]),
Sut::parse(toks.into_iter()).collect(), sut_parse(toks.into_iter()).collect(),
); );
} }
@ -77,7 +98,7 @@ fn calc_exprs() {
O(Air::ExprEnd(S3)), O(Air::ExprEnd(S3)),
O(Air::ExprEnd(S4)), O(Air::ExprEnd(S4)),
]), ]),
Sut::parse(toks.into_iter()).collect(), sut_parse(toks.into_iter()).collect(),
); );
} }
@ -99,7 +120,7 @@ fn classify_to_conj_expr() {
O(Air::BindIdent(id)), O(Air::BindIdent(id)),
O(Air::ExprEnd(S3)), O(Air::ExprEnd(S3)),
]), ]),
Sut::parse(toks.into_iter()).collect(), sut_parse(toks.into_iter()).collect(),
); );
} }
@ -121,7 +142,7 @@ fn logic_exprs() {
O(Air::ExprEnd(S3)), O(Air::ExprEnd(S3)),
O(Air::ExprEnd(S4)), O(Air::ExprEnd(S4)),
]), ]),
Sut::parse(toks.into_iter()).collect(), sut_parse(toks.into_iter()).collect(),
); );
} }
@ -148,7 +169,7 @@ fn desc_as_indep_clause() {
O(Air::DocIndepClause(desc)), O(Air::DocIndepClause(desc)),
O(Air::ExprEnd(S4)), O(Air::ExprEnd(S4)),
]), ]),
Sut::parse(toks.into_iter()).collect(), sut_parse(toks.into_iter()).collect(),
); );
} }
@ -170,7 +191,7 @@ fn tpl_with_name() {
O(Air::BindIdent(name)), O(Air::BindIdent(name)),
O(Air::TplEnd(S3)), O(Air::TplEnd(S3)),
]), ]),
Sut::parse(toks.into_iter()).collect(), sut_parse(toks.into_iter()).collect(),
); );
} }
@ -194,7 +215,7 @@ fn apply_template_long_form_nullary() {
O(Air::RefIdent(name)), O(Air::RefIdent(name)),
O(Air::TplEndRef(S3)), O(Air::TplEndRef(S3)),
]), ]),
Sut::parse(toks.into_iter()).collect(), sut_parse(toks.into_iter()).collect(),
); );
} }
@ -240,7 +261,7 @@ fn apply_template_long_form_args() {
O(Air::MetaEnd(S10)), O(Air::MetaEnd(S10)),
O(Air::TplEndRef(S11)), O(Air::TplEndRef(S11)),
]), ]),
Sut::parse(toks.into_iter()).collect(), sut_parse(toks.into_iter()).collect(),
); );
} }
@ -274,7 +295,7 @@ fn match_short_no_value() {
O(Air::RefIdent(SPair(SYM_TRUE, S1))), O(Air::RefIdent(SPair(SYM_TRUE, S1))),
O(Air::ExprEnd(S3)), O(Air::ExprEnd(S3)),
]), ]),
Sut::parse(toks.into_iter()).collect(), sut_parse(toks.into_iter()).collect(),
); );
} }
@ -306,7 +327,7 @@ fn match_short_with_value() {
O(Air::RefIdent(value)), O(Air::RefIdent(value)),
O(Air::ExprEnd(S4)), O(Air::ExprEnd(S4)),
]), ]),
Sut::parse(toks.into_iter()).collect(), sut_parse(toks.into_iter()).collect(),
); );
} }
@ -345,7 +366,7 @@ fn match_short_value_before_subject_err() {
Ok(O(Air::RefIdent(SPair(SYM_TRUE, S1)))), Ok(O(Air::RefIdent(SPair(SYM_TRUE, S1)))),
Ok(O(Air::ExprEnd(S3))), Ok(O(Air::ExprEnd(S3))),
], ],
Sut::parse(toks.into_iter()).collect::<Vec<Result<_, _>>>(), sut_parse(toks.into_iter()).collect::<Vec<Result<_, _>>>(),
); );
} }
@ -370,7 +391,7 @@ fn match_no_args_err() {
)), )),
// RECOVERY: Useless match above discarded. // RECOVERY: Useless match above discarded.
], ],
Sut::parse(toks.into_iter()).collect::<Vec<Result<_, _>>>(), sut_parse(toks.into_iter()).collect::<Vec<Result<_, _>>>(),
); );
} }
@ -395,6 +416,6 @@ fn text_as_arbitrary_doc() {
O(Air::DocText(text)), O(Air::DocText(text)),
O(Air::PkgEnd(S3)), O(Air::PkgEnd(S3)),
]), ]),
Sut::parse(toks.into_iter()).collect(), sut_parse(toks.into_iter()).collect(),
); );
} }

View File

@ -152,7 +152,7 @@ lower_pipeline! {
|> XirfToNir |> XirfToNir
|> TplShortDesugar |> TplShortDesugar
|> InterpolateNir |> InterpolateNir
|> NirToAir |> NirToAir[nir_air_ty]
|> AirAggregate[air_ctx]; |> AirAggregate[air_ctx];
/// Lower an [`Asg`](crate::asg::Asg)-derived token stream into an /// Lower an [`Asg`](crate::asg::Asg)-derived token stream into an