tamer: tamec: Extract package parsing into pipeline module
The previous commit extracted xmlo loading, because that will be a common operation between `tamec` and `tameld`. This extracts parsing, which will only used by `tamec` for now, though components of the pipeline are similar to xmlo loading. Not only does it need to be removed from `tamec` and better abstracted, but the intent now is to get all of these things into one place so that the patterns are obviated and a better abstraction can be created to remove all of this boilerplate and type complexity. Furthermore, xmlo loading needs to use reporting and recovery, so having `parse_package_xml` here will help show how to make that happen easily. I'm pleased that it ended up being trivial to extract error reporting from the lowering pipeline as a simple (mutable) callback. I'm not pleased about the side-effects, but, this works well for now given how the system works today. DEV-13162
parent
57a805b495
commit
61753d77aa
|
@ -39,26 +39,21 @@ use std::{
|
|||
path::Path,
|
||||
};
|
||||
use tamer::{
|
||||
asg::{
|
||||
air::{Air, AirAggregate, AirAggregateCtx},
|
||||
AsgError, DefaultAsg,
|
||||
},
|
||||
asg::{air::Air, AsgError, DefaultAsg},
|
||||
diagnose::{
|
||||
AnnotatedSpan, Diagnostic, FsSpanResolver, Reporter, VisualReporter,
|
||||
},
|
||||
nir::{
|
||||
InterpError, InterpolateNir, Nir, NirToAir, NirToAirError,
|
||||
TplShortDesugar, XirfToNir, XirfToNirError,
|
||||
},
|
||||
nir::{InterpError, Nir, NirToAirError, XirfToNirError},
|
||||
parse::{
|
||||
lowerable, FinalizeError, Lower, ParseError, ParsedObject, Token,
|
||||
UnknownToken,
|
||||
},
|
||||
pipeline::parse_package_xml,
|
||||
xir::{
|
||||
self,
|
||||
flat::{RefinedText, XirToXirf, XirToXirfError, XirfToken},
|
||||
flat::{RefinedText, XirToXirfError, XirfToken},
|
||||
reader::XmlXirReader,
|
||||
DefaultEscaper, Error as XirError, Token as XirToken,
|
||||
DefaultEscaper, Token as XirToken,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -127,18 +122,14 @@ fn compile<R: Reporter>(
|
|||
|
||||
let mut ebuf = String::new();
|
||||
|
||||
fn report_err<R: Reporter>(
|
||||
e: &RecoverableError,
|
||||
reporter: &mut R,
|
||||
ebuf: &mut String,
|
||||
) -> Result<(), UnrecoverableError> {
|
||||
let report_err = |e: &RecoverableError| {
|
||||
// See below note about buffering.
|
||||
ebuf.clear();
|
||||
writeln!(ebuf, "{}", reporter.render(e))?;
|
||||
println!("{ebuf}");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Ok::<_, UnrecoverableError>(())
|
||||
};
|
||||
|
||||
// TODO: We're just echoing back out XIR,
|
||||
// which will be the same sans some formatting.
|
||||
|
@ -151,40 +142,15 @@ fn compile<R: Reporter>(
|
|||
{
|
||||
|_| ()
|
||||
}
|
||||
}))
|
||||
.map(|result| result.map_err(RecoverableError::from));
|
||||
}));
|
||||
|
||||
// TODO: Determine a good default capacity once we have this populated
|
||||
// and can come up with some heuristics.
|
||||
let air_ctx: AirAggregateCtx = DefaultAsg::with_capacity(1024, 2048).into();
|
||||
|
||||
let (_, air_ctx) = Lower::<
|
||||
ParsedObject<UnknownToken, XirToken, XirError>,
|
||||
XirToXirf<64, RefinedText>,
|
||||
_,
|
||||
>::lower::<_, UnrecoverableError>(src, |toks| {
|
||||
Lower::<XirToXirf<64, RefinedText>, XirfToNir, _>::lower(toks, |nir| {
|
||||
Lower::<XirfToNir, TplShortDesugar, _>::lower(nir, |nir| {
|
||||
Lower::<TplShortDesugar, InterpolateNir, _>::lower(nir, |nir| {
|
||||
Lower::<InterpolateNir, NirToAir, _>::lower(nir, |air| {
|
||||
Lower::<NirToAir, AirAggregate, _>::lower_with_context(
|
||||
air,
|
||||
air_ctx,
|
||||
|end| {
|
||||
end.fold(Ok(()), |x, result| match result {
|
||||
Ok(_) => x,
|
||||
Err(e) => {
|
||||
report_err(&e, reporter, &mut ebuf)?;
|
||||
x
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})?;
|
||||
let air_ctx = parse_package_xml(
|
||||
src,
|
||||
DefaultAsg::with_capacity(1024, 2048).into(),
|
||||
report_err,
|
||||
)?;
|
||||
|
||||
match reporter.has_errors() {
|
||||
false => {
|
||||
|
|
|
@ -43,13 +43,14 @@
|
|||
use crate::{
|
||||
asg::air::{AirAggregate, AirAggregateCtx},
|
||||
diagnose::Diagnostic,
|
||||
nir::{InterpolateNir, NirToAir, TplShortDesugar, XirfToNir},
|
||||
obj::xmlo::{XmloAirContext, XmloReader, XmloToAir, XmloToken},
|
||||
parse::{
|
||||
FinalizeError, FromParseError, Lower, LowerSource, ParseError, Parsed,
|
||||
ParsedObject, UnknownToken,
|
||||
},
|
||||
xir::{
|
||||
flat::{PartialXirToXirf, Text},
|
||||
flat::{PartialXirToXirf, RefinedText, Text, XirToXirf},
|
||||
Error as XirError, Token as XirToken,
|
||||
},
|
||||
};
|
||||
|
@ -63,13 +64,13 @@ use crate::{
|
|||
/// TODO: To re-use this in `tamec` we want to be able to ignore fragments.
|
||||
///
|
||||
/// TODO: More documentation once this has been further cleaned up.
|
||||
pub fn load_xmlo<EO: Diagnostic + PartialEq>(
|
||||
pub fn load_xmlo<EU: Diagnostic + PartialEq>(
|
||||
src: impl LowerSource<UnknownToken, XirToken, XirError>,
|
||||
air_ctx: AirAggregateCtx,
|
||||
xmlo_ctx: XmloAirContext,
|
||||
) -> Result<(AirAggregateCtx, XmloAirContext), EO>
|
||||
) -> Result<(AirAggregateCtx, XmloAirContext), EU>
|
||||
where
|
||||
EO: From<ParseError<UnknownToken, XirError>>
|
||||
EU: From<ParseError<UnknownToken, XirError>>
|
||||
+ FromParseError<PartialXirToXirf<4, Text>>
|
||||
+ FromParseError<XmloReader>
|
||||
+ FromParseError<XmloToAir>
|
||||
|
@ -81,8 +82,8 @@ where
|
|||
Lower::<
|
||||
ParsedObject<UnknownToken, XirToken, XirError>,
|
||||
PartialXirToXirf<4, Text>,
|
||||
EO,
|
||||
>::lower(&mut src.map(|result| result.map_err(EO::from)), |toks| {
|
||||
EU,
|
||||
>::lower(&mut src.map(|result| result.map_err(EU::from)), |toks| {
|
||||
Lower::<PartialXirToXirf<4, Text>, XmloReader, _>::lower(toks, |xmlo| {
|
||||
let mut iter = xmlo.scan(false, |st, rtok| match st {
|
||||
true => None,
|
||||
|
@ -106,13 +107,60 @@ where
|
|||
let _ = result?;
|
||||
}
|
||||
|
||||
Ok::<_, EO>(())
|
||||
Ok::<_, EU>(())
|
||||
},
|
||||
)?;
|
||||
|
||||
Ok::<_, EO>(air_ctx)
|
||||
Ok::<_, EU>(air_ctx)
|
||||
},
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Parse a source package into the [ASG](crate::asg) using TAME's XML
|
||||
/// source language.
|
||||
///
|
||||
/// TODO: More documentation once this has been further cleaned up.
|
||||
pub fn parse_package_xml<ER: Diagnostic, EU: Diagnostic>(
|
||||
src: impl LowerSource<UnknownToken, XirToken, XirError>,
|
||||
air_ctx: AirAggregateCtx,
|
||||
mut report_err: impl FnMut(&ER) -> Result<(), EU>,
|
||||
) -> Result<AirAggregateCtx, EU>
|
||||
where
|
||||
ER: From<ParseError<UnknownToken, XirError>>
|
||||
+ FromParseError<XirToXirf<64, Text>>
|
||||
+ FromParseError<XirfToNir>
|
||||
+ FromParseError<TplShortDesugar>
|
||||
+ FromParseError<InterpolateNir>
|
||||
+ FromParseError<NirToAir>
|
||||
+ FromParseError<AirAggregate>,
|
||||
EU: From<FinalizeError>,
|
||||
{
|
||||
#[rustfmt::skip] // better visualize the structure despite the line length
|
||||
let (_, air_ctx) = Lower::<
|
||||
ParsedObject<UnknownToken, XirToken, XirError>,
|
||||
XirToXirf<64, RefinedText>,
|
||||
_,
|
||||
>::lower::<_, EU>(&mut src.map(|result| result.map_err(ER::from)), |toks| {
|
||||
Lower::<XirToXirf<64, RefinedText>, XirfToNir, _>::lower(toks, |nir| {
|
||||
Lower::<XirfToNir, TplShortDesugar, _>::lower(nir, |nir| {
|
||||
Lower::<TplShortDesugar, InterpolateNir, _>::lower(nir, |nir| {
|
||||
Lower::<InterpolateNir, NirToAir, _>::lower(nir, |air| {
|
||||
Lower::<NirToAir, AirAggregate, _>::lower_with_context(air, air_ctx, |end| {
|
||||
end.fold(Ok(()), |x, result| match result {
|
||||
Ok(_) => x,
|
||||
Err(e) => {
|
||||
report_err(&e)?;
|
||||
x
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})?;
|
||||
|
||||
Ok(air_ctx)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue