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-13162main
parent
61d556c89e
commit
341af3fdaf
|
@ -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 => {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue