tamer: asg::graph::xmli: Extract xmli generation from parse_token
This begins to develop a pattern for doing these transformations. I had tried a number of things using iterators, but I wasn't satisfied with either how they were turning out; had to fight too much with the type system; or had to resort to heap allocations. Sticking with an explicit `push`/`push_all` for now works just fine. Almost done cleaning up `AsgTreeToXirf::parse_token`, and then I can move on to introducing more objects. DEV-13708main
parent
9eb1d226b2
commit
e3e50c38c7
|
@ -30,7 +30,8 @@
|
|||
//! or observing template expansions.
|
||||
|
||||
use super::object::{
|
||||
DynObjectRel, Expr, Object, ObjectIndex, ObjectRelTy, Pkg,
|
||||
DynObjectRel, Expr, Object, ObjectIndex, ObjectRelTy, OiPairObjectInner,
|
||||
Pkg,
|
||||
};
|
||||
use crate::{
|
||||
asg::{
|
||||
|
@ -39,7 +40,7 @@ use crate::{
|
|||
},
|
||||
diagnose::Annotate,
|
||||
diagnostic_panic, diagnostic_unreachable,
|
||||
parse::{prelude::*, util::SPair},
|
||||
parse::{prelude::*, util::SPair, Transitionable},
|
||||
span::{Span, UNKNOWN_SPAN},
|
||||
sym::{
|
||||
st::{URI_LV_CALC, URI_LV_RATER, URI_LV_TPL},
|
||||
|
@ -99,36 +100,24 @@ impl<'a> ParseState for AsgTreeToXirf<'a> {
|
|||
// resolution in branches that do not utilize the source.
|
||||
let paired_rel = dyn_rel.resolve_oi_pairs(asg);
|
||||
|
||||
match paired_rel.target() {
|
||||
Object::Pkg((pkg, _)) => {
|
||||
let span = pkg.span();
|
||||
|
||||
toks.push_all([
|
||||
ns(QN_XMLNS_T, URI_LV_TPL, span),
|
||||
ns(QN_XMLNS_C, URI_LV_CALC, span),
|
||||
ns(QN_XMLNS, URI_LV_RATER, span),
|
||||
]);
|
||||
|
||||
Transition(self).ok(package(pkg, depth))
|
||||
}
|
||||
let xirf_tok = match paired_rel.target() {
|
||||
Object::Pkg((pkg, _)) => emit_package(toks, pkg, depth),
|
||||
|
||||
// Identifiers will be considered in context;
|
||||
// pass over it for now.
|
||||
Object::Ident(..) => Transition(self).incomplete(),
|
||||
Object::Ident(..) => None,
|
||||
|
||||
Object::Expr((expr, _)) => match paired_rel.source() {
|
||||
Object::Ident((ident, _)) => {
|
||||
toks.push(yields(ident.name(), expr.span()));
|
||||
Transition(self).ok(stmt(expr, depth))
|
||||
}
|
||||
_ => Transition(self).ok(expr_ele(expr, depth)),
|
||||
},
|
||||
Object::Expr((expr, _)) => {
|
||||
emit_expr(toks, expr, paired_rel.source(), depth)
|
||||
}
|
||||
|
||||
Object::Root(..) => diagnostic_unreachable!(
|
||||
vec![tok_span.error("unexpected Root")],
|
||||
"tree walk is not expected to emit Root",
|
||||
),
|
||||
}
|
||||
};
|
||||
|
||||
xirf_tok.transition(self)
|
||||
}
|
||||
|
||||
fn is_accepting(&self, TreeContext(toks, _): &Self::Context) -> bool {
|
||||
|
@ -157,6 +146,55 @@ impl<'a> ParseState for AsgTreeToXirf<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Emit tokens representing the root package element.
|
||||
fn emit_package(
|
||||
toks: &mut TokenStack,
|
||||
pkg: &Pkg,
|
||||
depth: Depth,
|
||||
) -> Option<Xirf> {
|
||||
let span = pkg.span();
|
||||
|
||||
toks.push_all([
|
||||
ns(QN_XMLNS_T, URI_LV_TPL, span),
|
||||
ns(QN_XMLNS_C, URI_LV_CALC, span),
|
||||
ns(QN_XMLNS, URI_LV_RATER, span),
|
||||
]);
|
||||
|
||||
Some(package(pkg, depth))
|
||||
}
|
||||
|
||||
/// Emit an expression as a legacy TAME statement or expression.
|
||||
///
|
||||
/// Identified expressions must be represented using statements in
|
||||
/// legacy TAME,
|
||||
/// such as `<rate>`.
|
||||
/// Anonymous expressions are nested within statements.
|
||||
///
|
||||
/// This system will emit statements and expressions that are compatible
|
||||
/// with the information on the [ASG](crate::asg) and recognized by the
|
||||
/// downstream XSLT-based compiler.
|
||||
/// There is no guarantee,
|
||||
/// however,
|
||||
/// that what is emitted is exactly representative of what the user
|
||||
/// originally entered.
|
||||
///
|
||||
/// Please ensure that the system matches your expectations using the system
|
||||
/// tests in `:tamer/tests/xmli`.
|
||||
fn emit_expr(
|
||||
toks: &mut TokenStack,
|
||||
expr: &Expr,
|
||||
src: &Object<OiPairObjectInner>,
|
||||
depth: Depth,
|
||||
) -> Option<Xirf> {
|
||||
match src {
|
||||
Object::Ident((ident, _)) => {
|
||||
toks.push(yields(ident.name(), expr.span()));
|
||||
Some(stmt(expr, depth))
|
||||
}
|
||||
_ => Some(expr_ele(expr, depth)),
|
||||
}
|
||||
}
|
||||
|
||||
fn package(pkg: &Pkg, depth: Depth) -> Xirf {
|
||||
Xirf::open(QN_PACKAGE, OpenSpan::without_name_span(pkg.span()), depth)
|
||||
}
|
||||
|
|
|
@ -681,6 +681,18 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<S> Transitionable<S> for Option<S::Object>
|
||||
where
|
||||
S: ParseState,
|
||||
{
|
||||
fn transition(self, to: S) -> TransitionResult<S::Super> {
|
||||
match self {
|
||||
Some(obj) => Transition(to).ok(obj),
|
||||
None => Transition(to).incomplete(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: ParseState> Transitionable<S> for ParseStatus<S> {
|
||||
fn transition(self, to: S) -> TransitionResult<S::Super> {
|
||||
Transition(to).ok(self.into_super())
|
||||
|
|
Loading…
Reference in New Issue