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-13708
main
Mike Gerwitz 2023-03-30 15:41:17 -04:00
parent f29e3cfce1
commit 558f1c96b1
3 changed files with 25 additions and 47 deletions

View File

@ -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)
}

View File

@ -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;
}

View File

@ -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),
}
}