tamer: tamec: Extract xmli lowering into pipeline module
This is the same idea as the previous two commits: get all the lowering pipelines into the same place so that we can observe commonalities and attempt to derive an appropriate abstraction. `lower_xmli` could have invoked `tree_reconstruction` itself, since it has all the information that it needs to do so, but the idea is that these will accept sources from the caller. This also demonstrates that sinks need to be flexible. In an ideal abstraction, perhaps this would be able to produce an iterator that accepts the first token type and yields the last, which can then be directed to a sink, but that's not compatible with how the lowering operations currently work, which requires a single value to be returned. But if it did work that way, then they'd be able to compose just as any other parser. Maybe for the future. DEV-13162
parent
61753d77aa
commit
db1d64f6fc
|
@ -44,10 +44,7 @@ use tamer::{
|
|||
AnnotatedSpan, Diagnostic, FsSpanResolver, Reporter, VisualReporter,
|
||||
},
|
||||
nir::{InterpError, Nir, NirToAirError, XirfToNirError},
|
||||
parse::{
|
||||
lowerable, FinalizeError, Lower, ParseError, ParsedObject, Token,
|
||||
UnknownToken,
|
||||
},
|
||||
parse::{lowerable, FinalizeError, ParseError, Token, UnknownToken},
|
||||
pipeline::parse_package_xml,
|
||||
xir::{
|
||||
self,
|
||||
|
@ -189,61 +186,16 @@ fn derive_xmli(
|
|||
escaper: &DefaultEscaper,
|
||||
) -> Result<(), UnrecoverableError> {
|
||||
use tamer::{
|
||||
asg::{
|
||||
visit::{tree_reconstruction, TreeWalkRel},
|
||||
AsgTreeToXirf,
|
||||
},
|
||||
iter::TrippableIterator,
|
||||
parse::terminal,
|
||||
xir::{
|
||||
autoclose::XirfAutoClose,
|
||||
flat::{Text, XirfToXir},
|
||||
writer::XmlWriter,
|
||||
},
|
||||
asg::visit::tree_reconstruction, pipeline, xir::writer::XmlWriter,
|
||||
};
|
||||
|
||||
let mut head =
|
||||
lowerable::<UnknownToken, _, _>(tree_reconstruction(&asg).map(Ok))
|
||||
.map(|result| result.map_err(UnrecoverableError::from));
|
||||
let src = lowerable(tree_reconstruction(&asg).map(Ok));
|
||||
|
||||
// THIS IS A PROOF-OF-CONCEPT LOWERING PIPELINE.
|
||||
Lower::<
|
||||
ParsedObject<UnknownToken, TreeWalkRel, Infallible>,
|
||||
AsgTreeToXirf,
|
||||
_,
|
||||
>::lower_with_context::<_, UnrecoverableError>(
|
||||
&mut head,
|
||||
&asg,
|
||||
|xirf_unclosed| {
|
||||
Lower::<AsgTreeToXirf, XirfAutoClose, _>::lower(
|
||||
xirf_unclosed,
|
||||
|xirf| {
|
||||
Lower::<XirfAutoClose, XirfToXir<Text>, _>::lower(
|
||||
xirf,
|
||||
|xir| {
|
||||
terminal::<XirfToXir<Text>, _>(xir).while_ok(
|
||||
|toks| {
|
||||
// Write failures should immediately bail out;
|
||||
// we can't skip writing portions of the file and
|
||||
// just keep going!
|
||||
toks.write(
|
||||
&mut fout,
|
||||
Default::default(),
|
||||
escaper,
|
||||
)?;
|
||||
Ok::<_, UnrecoverableError>(())
|
||||
},
|
||||
// TODO: Remove bad file?
|
||||
// Let make do it?
|
||||
)
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
// TODO: Remove bad file?
|
||||
// Let make do it?
|
||||
pipeline::lower_xmli(src, &asg, |st, tok| {
|
||||
tok.write(&mut fout, st, escaper).map_err(Into::into)
|
||||
})
|
||||
}
|
||||
|
||||
/// Entrypoint for the compiler
|
||||
|
|
|
@ -40,17 +40,26 @@
|
|||
//! For information on the lowering pipeline as an abstraction,
|
||||
//! see [`Lower`].
|
||||
|
||||
use std::convert::Infallible;
|
||||
|
||||
use crate::{
|
||||
asg::air::{AirAggregate, AirAggregateCtx},
|
||||
asg::{
|
||||
air::{AirAggregate, AirAggregateCtx},
|
||||
visit::TreeWalkRel,
|
||||
Asg, AsgTreeToXirf,
|
||||
},
|
||||
diagnose::Diagnostic,
|
||||
iter::TrippableIterator,
|
||||
nir::{InterpolateNir, NirToAir, TplShortDesugar, XirfToNir},
|
||||
obj::xmlo::{XmloAirContext, XmloReader, XmloToAir, XmloToken},
|
||||
parse::{
|
||||
FinalizeError, FromParseError, Lower, LowerSource, ParseError, Parsed,
|
||||
ParsedObject, UnknownToken,
|
||||
terminal, FinalizeError, FromParseError, Lower, LowerSource,
|
||||
ParseError, Parsed, ParsedObject, UnknownToken,
|
||||
},
|
||||
xir::{
|
||||
flat::{PartialXirToXirf, RefinedText, Text, XirToXirf},
|
||||
autoclose::XirfAutoClose,
|
||||
flat::{PartialXirToXirf, RefinedText, Text, XirToXirf, XirfToXir},
|
||||
writer::WriterState,
|
||||
Error as XirError, Token as XirToken,
|
||||
},
|
||||
};
|
||||
|
@ -164,3 +173,43 @@ where
|
|||
|
||||
Ok(air_ctx)
|
||||
}
|
||||
|
||||
/// Lower an [`Asg`]-derived token stream into an `xmli` file.
|
||||
///
|
||||
/// TODO: More documentation once this has been further cleaned up.
|
||||
pub fn lower_xmli<EU: Diagnostic>(
|
||||
src: impl LowerSource<UnknownToken, TreeWalkRel, Infallible>,
|
||||
asg: &Asg,
|
||||
sink: impl FnMut(WriterState, XirToken) -> Result<WriterState, EU>,
|
||||
) -> Result<(), EU>
|
||||
where
|
||||
EU: From<ParseError<UnknownToken, Infallible>>
|
||||
+ From<ParseError<TreeWalkRel, Infallible>> // see note above
|
||||
+ FromParseError<XirfAutoClose>
|
||||
+ FromParseError<XirfToXir<Text>>
|
||||
+ From<FinalizeError>,
|
||||
{
|
||||
#[rustfmt::skip] // better visualize the structure despite the line length
|
||||
Lower::<
|
||||
ParsedObject<UnknownToken, TreeWalkRel, Infallible>,
|
||||
AsgTreeToXirf,
|
||||
_,
|
||||
>::lower_with_context::<_, EU>(
|
||||
&mut src.map(|result| result.map_err(EU::from)),
|
||||
asg,
|
||||
|xirf_unclosed| {
|
||||
Lower::<AsgTreeToXirf, XirfAutoClose, _>::lower(xirf_unclosed, |xirf| {
|
||||
Lower::<XirfAutoClose, XirfToXir<Text>, _>::lower(xirf, |xir| {
|
||||
terminal::<XirfToXir<Text>, _>(xir).while_ok(|toks| {
|
||||
// Write failures should immediately bail out;
|
||||
// we can't skip writing portions of the file and
|
||||
// just keep going!
|
||||
toks.try_fold(Default::default(), sink)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue