tamer: asg::air: Restrict AirTplAggregate token domain to new AirTemplatable
This removes special cases, but it does complicate the parent `AirAggregate` parser. A pattern of delegation is forming, though abstracting it may be an interesting challenge, given Rust's limitation on macro invocations as match arms. But, I think I can manage by generating the entire match using a macro with a match-compatible syntax, augmenting where needed...maybe. This'll be messy. ...but if I can write the nightmare that is `ele_parse!`, I'm sure I can manage this. I just prefer to avoid complex macros unless I really need them. DEV-13708main
parent
2233c69bbf
commit
0e42788dcc
|
@ -187,10 +187,19 @@ impl ParseState for AirAggregate {
|
|||
Self::delegate_expr(asg, oi_pkg, expr, etok)
|
||||
}
|
||||
|
||||
// Templates can contain just about anything,
|
||||
// so completely hand over parsing when we're in template mode.
|
||||
(PkgTpl(oi_pkg, stored_expr, tplst), tok) => {
|
||||
Self::delegate_tpl(asg, oi_pkg, stored_expr, tplst, tok.into())
|
||||
// Template parsing.
|
||||
(PkgTpl(oi_pkg, stored_expr, tplst), AirExpr(ttok)) => {
|
||||
Self::delegate_tpl(asg, oi_pkg, stored_expr, tplst, ttok)
|
||||
}
|
||||
(PkgTpl(oi_pkg, stored_expr, tplst), AirBind(ttok)) => {
|
||||
Self::delegate_tpl(asg, oi_pkg, stored_expr, tplst, ttok)
|
||||
}
|
||||
(PkgTpl(oi_pkg, stored_expr, tplst), AirTpl(ttok)) => {
|
||||
Self::delegate_tpl(asg, oi_pkg, stored_expr, tplst, ttok)
|
||||
}
|
||||
|
||||
(PkgTpl(..), AirPkg(PkgOpen(..))) => {
|
||||
todo!("templates cannot contain packages")
|
||||
}
|
||||
|
||||
(Empty, AirTpl(TplClose(..))) => {
|
||||
|
@ -213,6 +222,16 @@ impl ParseState for AirAggregate {
|
|||
}
|
||||
}
|
||||
|
||||
(PkgTpl(oi_pkg, stored_expr, tplst), AirPkg(PkgClose(span))) => {
|
||||
match tplst.is_accepting(asg) {
|
||||
true => Transition(PkgExpr(oi_pkg, stored_expr))
|
||||
.incomplete()
|
||||
.with_lookahead(AirPkg(PkgClose(span))),
|
||||
false => Transition(PkgTpl(oi_pkg, stored_expr, tplst))
|
||||
.err(AsgError::InvalidPkgCloseContext(span)),
|
||||
}
|
||||
}
|
||||
|
||||
(Empty, tok @ (AirExpr(..) | AirBind(..) | AirTpl(TplOpen(_)))) => {
|
||||
Transition(Empty).err(AsgError::PkgExpected(tok.span()))
|
||||
}
|
||||
|
@ -287,9 +306,9 @@ impl AirAggregate {
|
|||
oi_pkg: ObjectIndex<Pkg>,
|
||||
stored_expr: AirExprAggregateReachable<Pkg>,
|
||||
tplst: AirTplAggregate,
|
||||
tok: Air,
|
||||
ttok: impl Into<<AirTplAggregate as ParseState>::Token>,
|
||||
) -> TransitionResult<Self> {
|
||||
tplst.parse_token(tok, asg).branch_dead::<Self, _>(
|
||||
tplst.parse_token(ttok.into(), asg).branch_dead::<Self, _>(
|
||||
|_, stored_expr| {
|
||||
Transition(Self::PkgExpr(oi_pkg, stored_expr)).incomplete()
|
||||
},
|
||||
|
|
|
@ -334,6 +334,7 @@ macro_rules! sum_ir {
|
|||
// subtypes.
|
||||
$(
|
||||
$(#[$sumattr])*
|
||||
#[allow(clippy::enum_variant_names)] // intentional consistency
|
||||
#[derive(Debug, PartialEq)]
|
||||
$sumvis enum $sumsub {
|
||||
$(
|
||||
|
@ -637,4 +638,16 @@ sum_ir! {
|
|||
/// This is the primary token set when parsing packages,
|
||||
/// since most everything in TAMER is an expression.
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,8 @@ use super::{
|
|||
Asg, AsgError, ObjectIndex,
|
||||
},
|
||||
expr::AirExprAggregateStoreDangling,
|
||||
Air, AirExprAggregate,
|
||||
ir::AirTemplatable,
|
||||
AirExprAggregate,
|
||||
};
|
||||
use crate::{
|
||||
fmt::{DisplayWrapper, TtQuote},
|
||||
|
@ -40,9 +41,9 @@ use crate::{
|
|||
///
|
||||
/// - Metadata about the template,
|
||||
/// including its parameters; and
|
||||
/// - A collection of [`Air`] tokens representing the body of the
|
||||
/// template that will be expanded into the application site when the
|
||||
/// template is applied.
|
||||
/// - A collection of [`AirTemplatable`] tokens 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
|
||||
|
@ -98,7 +99,7 @@ impl Display for AirTplAggregate {
|
|||
}
|
||||
|
||||
impl ParseState for AirTplAggregate {
|
||||
type Token = Air;
|
||||
type Token = AirTemplatable;
|
||||
type Object = ();
|
||||
type Error = AsgError;
|
||||
type Context = Asg;
|
||||
|
@ -108,12 +109,11 @@ impl ParseState for AirTplAggregate {
|
|||
tok: Self::Token,
|
||||
asg: &mut Self::Context,
|
||||
) -> TransitionResult<Self::Super> {
|
||||
use super::ir::{AirBind::*, AirSubsets::*, AirTodo::*, AirTpl::*};
|
||||
use super::ir::{AirBind::*, AirTpl::*};
|
||||
use AirTemplatable::*;
|
||||
use AirTplAggregate::*;
|
||||
|
||||
match (self, tok.into()) {
|
||||
(st, AirTodo(Todo(_))) => Transition(st).incomplete(),
|
||||
|
||||
match (self, tok) {
|
||||
(Ready(oi_pkg), AirTpl(TplOpen(span))) => {
|
||||
let oi_tpl = asg.create(Tpl::new(span));
|
||||
|
||||
|
@ -161,14 +161,6 @@ impl ParseState for AirTplAggregate {
|
|||
}
|
||||
}
|
||||
|
||||
(Toplevel(..) | TplExpr(..), AirPkg(_)) => {
|
||||
todo!("template cannot define packages")
|
||||
}
|
||||
|
||||
(Toplevel(..) | TplExpr(..), AirIdent(_)) => {
|
||||
todo!("linker token cannot be used in templates")
|
||||
}
|
||||
|
||||
(
|
||||
Toplevel(oi_pkg, oi_tpl, expr, name)
|
||||
| TplExpr(oi_pkg, oi_tpl, expr, name),
|
||||
|
@ -187,10 +179,9 @@ impl ParseState for AirTplAggregate {
|
|||
Transition(st).err(AsgError::UnbalancedTpl(span))
|
||||
}
|
||||
|
||||
(
|
||||
st @ Ready(..),
|
||||
tok @ (AirPkg(..) | AirExpr(..) | AirBind(..) | AirIdent(..)),
|
||||
) => Transition(st).dead(tok.into()),
|
||||
(st @ Ready(..), tok @ (AirExpr(..) | AirBind(..))) => {
|
||||
Transition(st).dead(tok)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue