tamer: asg::air: Extra AirExpr parsing from AirTplAggregate
This has AirAggregate preempt Expr parsing in the same way as templates, rather than having `AirTplAggregate` concern itself with expression tokens. This continues to simplify `AirTplAggregate`, which was getting quite complex not too long ago. A pattern is now emerging for the call/ret convention for preemption. That was intentional, but it's nice to see it manifest so obviously before I abstract it away. DEV-13708main
parent
f29e3cfce1
commit
558f1c96b1
|
@ -171,13 +171,20 @@ impl ParseState for AirAggregate {
|
|||
Transition(st).err(AsgError::InvalidExprRefContext(id))
|
||||
}
|
||||
|
||||
(Toplevel(oi_pkg), tok @ AirExpr(..)) => {
|
||||
ctx.stack().transfer_with_ret(
|
||||
Transition(Toplevel(oi_pkg)),
|
||||
Transition(AirExprAggregate::new())
|
||||
.incomplete()
|
||||
.with_lookahead(tok),
|
||||
)
|
||||
// TODO: This looks a whole lot like the match arm below.
|
||||
(st @ (Toplevel(_) | PkgTpl(_)), tok @ AirExpr(..)) => {
|
||||
// TODO: generalize this construction
|
||||
if st.active_is_accepting(ctx) {
|
||||
// TODO: dead state or error
|
||||
ctx.stack().ret_or_dead(Empty, tok)
|
||||
} else {
|
||||
ctx.stack().transfer_with_ret(
|
||||
Transition(st),
|
||||
Transition(AirExprAggregate::new())
|
||||
.incomplete()
|
||||
.with_lookahead(tok),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
(st @ (Toplevel(_) | PkgExpr(_)), tok @ AirTpl(..)) => {
|
||||
|
@ -208,9 +215,6 @@ impl ParseState for AirAggregate {
|
|||
}
|
||||
|
||||
// Template parsing.
|
||||
(PkgTpl(tplst), AirExpr(ttok)) => {
|
||||
Self::delegate_tpl(ctx, tplst, ttok)
|
||||
}
|
||||
(PkgTpl(tplst), AirBind(ttok)) => {
|
||||
Self::delegate_tpl(ctx, tplst, ttok)
|
||||
}
|
||||
|
|
|
@ -777,14 +777,5 @@ sum_ir! {
|
|||
pub sum enum AirBindableExpr = AirExpr | AirBind;
|
||||
|
||||
/// Tokens that may be used to define or apply templates.
|
||||
pub sum enum AirTemplatable = AirExpr | AirBind | AirTpl;
|
||||
}
|
||||
|
||||
impl From<AirBindableExpr> for AirTemplatable {
|
||||
fn from(expr: AirBindableExpr) -> Self {
|
||||
match expr {
|
||||
AirBindableExpr::AirExpr(x) => Self::AirExpr(x),
|
||||
AirBindableExpr::AirBind(x) => Self::AirBind(x),
|
||||
}
|
||||
}
|
||||
pub sum enum AirBindableTpl = AirTpl | AirBind;
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
|
||||
use super::{
|
||||
super::{graph::object::Tpl, Asg, AsgError, ObjectIndex},
|
||||
ir::AirTemplatable,
|
||||
AirAggregate, AirAggregateCtx, AirExprAggregate,
|
||||
ir::AirBindableTpl,
|
||||
AirAggregate, AirAggregateCtx,
|
||||
};
|
||||
use crate::{
|
||||
asg::graph::object::{Meta, ObjectIndexRelTo},
|
||||
|
@ -41,13 +41,12 @@ use crate::{
|
|||
///
|
||||
/// - Metadata about the template,
|
||||
/// including its parameters; and
|
||||
/// - A collection of [`AirTemplatable`] tokens representing the body of
|
||||
/// the template that will be expanded into the application site when
|
||||
/// the template is applied.
|
||||
/// - A collection of objects representing the body of the template that
|
||||
/// will be expanded into the application site when the template is
|
||||
/// applied.
|
||||
///
|
||||
/// This contains an embedded [`AirExprAggregate`] parser for handling
|
||||
/// expressions just the same as [`super::AirAggregate`] does with
|
||||
/// packages.
|
||||
/// The superstate is expected to preempt this parser for expression
|
||||
/// parsing.
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum AirTplAggregate {
|
||||
/// Ready for a template,
|
||||
|
@ -156,7 +155,7 @@ impl Display for TplState {
|
|||
}
|
||||
|
||||
impl ParseState for AirTplAggregate {
|
||||
type Token = AirTemplatable;
|
||||
type Token = AirBindableTpl;
|
||||
type Object = ();
|
||||
type Error = AsgError;
|
||||
type Context = AirAggregateCtx;
|
||||
|
@ -168,7 +167,7 @@ impl ParseState for AirTplAggregate {
|
|||
ctx: &mut Self::Context,
|
||||
) -> TransitionResult<Self::Super> {
|
||||
use super::ir::{AirBind::*, AirTpl::*};
|
||||
use AirTemplatable::*;
|
||||
use AirBindableTpl::*;
|
||||
use AirTplAggregate::*;
|
||||
|
||||
match (self, tok) {
|
||||
|
@ -225,13 +224,6 @@ impl ParseState for AirTplAggregate {
|
|||
)
|
||||
}
|
||||
|
||||
(TplMeta(..), tok @ AirExpr(..)) => {
|
||||
diagnostic_todo!(
|
||||
vec![tok.note("this token")],
|
||||
"AirExpr in metavar context (e.g. @values@)"
|
||||
)
|
||||
}
|
||||
|
||||
(
|
||||
TplMeta(..),
|
||||
tok @ AirTpl(
|
||||
|
@ -269,13 +261,6 @@ impl ParseState for AirTplAggregate {
|
|||
.with_lookahead(AirTpl(TplEnd(span)))
|
||||
}
|
||||
|
||||
(Toplevel(tpl), tok @ AirExpr(_)) => ctx.stack().transfer_with_ret(
|
||||
Transition(Toplevel(tpl)),
|
||||
Transition(AirExprAggregate::new())
|
||||
.incomplete()
|
||||
.with_lookahead(tok),
|
||||
),
|
||||
|
||||
(
|
||||
Ready,
|
||||
tok @ AirTpl(TplMetaStart(..) | TplLexeme(..) | TplMetaEnd(..)),
|
||||
|
@ -290,9 +275,7 @@ impl ParseState for AirTplAggregate {
|
|||
Transition(st).err(AsgError::UnbalancedTpl(span))
|
||||
}
|
||||
|
||||
(st @ Ready, tok @ (AirExpr(..) | AirBind(..))) => {
|
||||
Transition(st).dead(tok)
|
||||
}
|
||||
(st @ Ready, tok @ AirBind(..)) => Transition(st).dead(tok),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue