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)
|
Self::delegate_expr(asg, oi_pkg, expr, etok)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Templates can contain just about anything,
|
// Template parsing.
|
||||||
// so completely hand over parsing when we're in template mode.
|
(PkgTpl(oi_pkg, stored_expr, tplst), AirExpr(ttok)) => {
|
||||||
(PkgTpl(oi_pkg, stored_expr, tplst), tok) => {
|
Self::delegate_tpl(asg, oi_pkg, stored_expr, tplst, ttok)
|
||||||
Self::delegate_tpl(asg, oi_pkg, stored_expr, tplst, tok.into())
|
}
|
||||||
|
(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(..))) => {
|
(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(_)))) => {
|
(Empty, tok @ (AirExpr(..) | AirBind(..) | AirTpl(TplOpen(_)))) => {
|
||||||
Transition(Empty).err(AsgError::PkgExpected(tok.span()))
|
Transition(Empty).err(AsgError::PkgExpected(tok.span()))
|
||||||
}
|
}
|
||||||
|
@ -287,9 +306,9 @@ impl AirAggregate {
|
||||||
oi_pkg: ObjectIndex<Pkg>,
|
oi_pkg: ObjectIndex<Pkg>,
|
||||||
stored_expr: AirExprAggregateReachable<Pkg>,
|
stored_expr: AirExprAggregateReachable<Pkg>,
|
||||||
tplst: AirTplAggregate,
|
tplst: AirTplAggregate,
|
||||||
tok: Air,
|
ttok: impl Into<<AirTplAggregate as ParseState>::Token>,
|
||||||
) -> TransitionResult<Self> {
|
) -> TransitionResult<Self> {
|
||||||
tplst.parse_token(tok, asg).branch_dead::<Self, _>(
|
tplst.parse_token(ttok.into(), asg).branch_dead::<Self, _>(
|
||||||
|_, stored_expr| {
|
|_, stored_expr| {
|
||||||
Transition(Self::PkgExpr(oi_pkg, stored_expr)).incomplete()
|
Transition(Self::PkgExpr(oi_pkg, stored_expr)).incomplete()
|
||||||
},
|
},
|
||||||
|
|
|
@ -334,6 +334,7 @@ macro_rules! sum_ir {
|
||||||
// subtypes.
|
// subtypes.
|
||||||
$(
|
$(
|
||||||
$(#[$sumattr])*
|
$(#[$sumattr])*
|
||||||
|
#[allow(clippy::enum_variant_names)] // intentional consistency
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
$sumvis enum $sumsub {
|
$sumvis enum $sumsub {
|
||||||
$(
|
$(
|
||||||
|
@ -637,4 +638,16 @@ sum_ir! {
|
||||||
/// This is the primary token set when parsing packages,
|
/// This is the primary token set when parsing packages,
|
||||||
/// since most everything in TAMER is an expression.
|
/// since most everything in TAMER is an expression.
|
||||||
pub sum enum AirBindableExpr = AirExpr | AirBind;
|
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,
|
Asg, AsgError, ObjectIndex,
|
||||||
},
|
},
|
||||||
expr::AirExprAggregateStoreDangling,
|
expr::AirExprAggregateStoreDangling,
|
||||||
Air, AirExprAggregate,
|
ir::AirTemplatable,
|
||||||
|
AirExprAggregate,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
fmt::{DisplayWrapper, TtQuote},
|
fmt::{DisplayWrapper, TtQuote},
|
||||||
|
@ -40,9 +41,9 @@ use crate::{
|
||||||
///
|
///
|
||||||
/// - Metadata about the template,
|
/// - Metadata about the template,
|
||||||
/// including its parameters; and
|
/// including its parameters; and
|
||||||
/// - A collection of [`Air`] tokens representing the body of the
|
/// - A collection of [`AirTemplatable`] tokens representing the body of
|
||||||
/// template that will be expanded into the application site when the
|
/// the template that will be expanded into the application site when
|
||||||
/// template is applied.
|
/// the template is applied.
|
||||||
///
|
///
|
||||||
/// This contains an embedded [`AirExprAggregate`] parser for handling
|
/// This contains an embedded [`AirExprAggregate`] parser for handling
|
||||||
/// expressions just the same as [`super::AirAggregate`] does with
|
/// expressions just the same as [`super::AirAggregate`] does with
|
||||||
|
@ -98,7 +99,7 @@ impl Display for AirTplAggregate {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParseState for AirTplAggregate {
|
impl ParseState for AirTplAggregate {
|
||||||
type Token = Air;
|
type Token = AirTemplatable;
|
||||||
type Object = ();
|
type Object = ();
|
||||||
type Error = AsgError;
|
type Error = AsgError;
|
||||||
type Context = Asg;
|
type Context = Asg;
|
||||||
|
@ -108,12 +109,11 @@ impl ParseState for AirTplAggregate {
|
||||||
tok: Self::Token,
|
tok: Self::Token,
|
||||||
asg: &mut Self::Context,
|
asg: &mut Self::Context,
|
||||||
) -> TransitionResult<Self::Super> {
|
) -> TransitionResult<Self::Super> {
|
||||||
use super::ir::{AirBind::*, AirSubsets::*, AirTodo::*, AirTpl::*};
|
use super::ir::{AirBind::*, AirTpl::*};
|
||||||
|
use AirTemplatable::*;
|
||||||
use AirTplAggregate::*;
|
use AirTplAggregate::*;
|
||||||
|
|
||||||
match (self, tok.into()) {
|
match (self, tok) {
|
||||||
(st, AirTodo(Todo(_))) => Transition(st).incomplete(),
|
|
||||||
|
|
||||||
(Ready(oi_pkg), AirTpl(TplOpen(span))) => {
|
(Ready(oi_pkg), AirTpl(TplOpen(span))) => {
|
||||||
let oi_tpl = asg.create(Tpl::new(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)
|
Toplevel(oi_pkg, oi_tpl, expr, name)
|
||||||
| TplExpr(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))
|
Transition(st).err(AsgError::UnbalancedTpl(span))
|
||||||
}
|
}
|
||||||
|
|
||||||
(
|
(st @ Ready(..), tok @ (AirExpr(..) | AirBind(..))) => {
|
||||||
st @ Ready(..),
|
Transition(st).dead(tok)
|
||||||
tok @ (AirPkg(..) | AirExpr(..) | AirBind(..) | AirIdent(..)),
|
}
|
||||||
) => Transition(st).dead(tok.into()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue