From 341af3fdaf7b55a825a11e46eb515aec9d37b922 Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Tue, 13 Jun 2023 15:07:03 -0400 Subject: [PATCH] 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 --- tamer/src/bin/tamec.rs | 13 +++++-- tamer/src/nir.rs | 2 +- tamer/src/nir/air.rs | 80 ++++++++++++++++++++++++++------------- tamer/src/nir/air/test.rs | 51 +++++++++++++++++-------- tamer/src/pipeline.rs | 2 +- 5 files changed, 102 insertions(+), 46 deletions(-) diff --git a/tamer/src/bin/tamec.rs b/tamer/src/bin/tamec.rs index 5801d25c..81607770 100644 --- a/tamer/src/bin/tamec.rs +++ b/tamer/src/bin/tamec.rs @@ -43,6 +43,7 @@ use tamer::{ diagnose::{ AnnotatedSpan, Diagnostic, FsSpanResolver, Reporter, VisualReporter, }, + nir::NirToAirParseType, parse::{lowerable, FinalizeError, ParseError, Token}, pipeline::{parse_package_xml, LowerXmliError, ParsePackageXmlError}, xir::{self, reader::XmlXirReader, DefaultEscaper}, @@ -137,11 +138,17 @@ fn compile( } })); + #[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 // and can come up with some heuristics. - let (air_ctx,) = parse_package_xml(DefaultAsg::with_capacity(1024, 2048))( - src, report_err, - )?; + let (_, air_ctx) = parse_package_xml( + parse_type, + DefaultAsg::with_capacity(1024, 2048), + )(src, report_err)?; match reporter.has_errors() { false => { diff --git a/tamer/src/nir.rs b/tamer/src/nir.rs index 6a4ee756..214ad1a9 100644 --- a/tamer/src/nir.rs +++ b/tamer/src/nir.rs @@ -72,7 +72,7 @@ use std::{ fmt::{Debug, Display}, }; -pub use air::{NirToAir, NirToAirError}; +pub use air::{NirToAir, NirToAirError, NirToAirParseType}; pub use interp::{InterpError, InterpState as InterpolateNir}; pub use parse::{ NirParseState as XirfToNir, NirParseStateError_ as XirfToNirError, diff --git a/tamer/src/nir/air.rs b/tamer/src/nir/air.rs index d543bc5d..422ba433 100644 --- a/tamer/src/nir/air.rs +++ b/tamer/src/nir/air.rs @@ -21,22 +21,58 @@ use super::Nir; use crate::{ - asg::air::Air, + asg::{air::Air, ExprOp}, diagnose::{Annotate, Diagnostic}, fmt::{DisplayWrapper, TtQuote}, + nir::{Nir::*, NirEntity::*}, parse::prelude::*, span::Span, + sym::{st::raw::U_TRUE, SymbolId}, }; use arrayvec::ArrayVec; use std::{error::Error, fmt::Display}; -// These are also used by the `test` module which imports `super`. -#[cfg(feature = "wip-asg-derived-xmli")] -use crate::{ - asg::ExprOp, - nir::{Nir::*, NirEntity::*}, - sym::{st::raw::U_TRUE, SymbolId}, -}; +/// Dynamic [`NirToAir`] parser configuration. +/// +/// This acts as a runtime feature flag while this portions of TAMER is +/// under development. +#[derive(Debug, PartialEq, Eq)] +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 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)] pub enum NirToAir { @@ -78,36 +114,28 @@ type ObjStack = ArrayVec; /// The symbol to use when lexically expanding shorthand notations to /// compare against values of `1`. -#[cfg(feature = "wip-asg-derived-xmli")] pub const SYM_TRUE: SymbolId = U_TRUE; impl ParseState for NirToAir { type Token = Nir; type Object = Air; type Error = NirToAirError; - type Context = ObjStack; + type Context = (NirToAirParseType, ObjStack); + type PubContext = NirToAirParseType; - #[cfg(not(feature = "wip-asg-derived-xmli"))] fn parse_token( self, tok: Self::Token, - _queue: &mut Self::Context, - ) -> TransitionResult { - 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, + (parse_type, stack): &mut Self::Context, ) -> TransitionResult { use NirToAir::*; use NirToAirError::*; + match parse_type { + NirToAirParseType::Noop => return Transition(Ready).incomplete(), + NirToAirParseType::LowerKnownErrorRest => (), + } + if let Some(obj) = stack.pop() { 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() } } @@ -364,5 +392,5 @@ impl Diagnostic for NirToAirError { } } -#[cfg(all(test, feature = "wip-asg-derived-xmli"))] +#[cfg(test)] mod test; diff --git a/tamer/src/nir/air/test.rs b/tamer/src/nir/air/test.rs index 7939453e..03abc7f4 100644 --- a/tamer/src/nir/air/test.rs +++ b/tamer/src/nir/air/test.rs @@ -18,12 +18,33 @@ // along with this program. If not, see . use super::*; -use crate::{parse::util::SPair, span::dummy::*}; +use crate::{ + parse::{util::SPair, Parser}, + span::dummy::*, +}; type Sut = NirToAir; use Parsed::{Incomplete, Object as O}; +fn sut_parse>(toks: I) -> Parser { + 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] fn package_to_pkg() { 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::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::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(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::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(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::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::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::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::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::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::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::ExprEnd(S3))), ], - Sut::parse(toks.into_iter()).collect::>>(), + sut_parse(toks.into_iter()).collect::>>(), ); } @@ -370,7 +391,7 @@ fn match_no_args_err() { )), // RECOVERY: Useless match above discarded. ], - Sut::parse(toks.into_iter()).collect::>>(), + sut_parse(toks.into_iter()).collect::>>(), ); } @@ -395,6 +416,6 @@ fn text_as_arbitrary_doc() { O(Air::DocText(text)), O(Air::PkgEnd(S3)), ]), - Sut::parse(toks.into_iter()).collect(), + sut_parse(toks.into_iter()).collect(), ); } diff --git a/tamer/src/pipeline.rs b/tamer/src/pipeline.rs index 151d7e18..4a078c1e 100644 --- a/tamer/src/pipeline.rs +++ b/tamer/src/pipeline.rs @@ -152,7 +152,7 @@ lower_pipeline! { |> XirfToNir |> TplShortDesugar |> InterpolateNir - |> NirToAir + |> NirToAir[nir_air_ty] |> AirAggregate[air_ctx]; /// Lower an [`Asg`](crate::asg::Asg)-derived token stream into an