tamer: asg::air: AirAggregateCtx: New AirAggregate::Context
Future changes to `AirAggregate` are going to require additional context (a stack, specifically), but the `Context` is currently utilized by `Asg`. This introduces a layer of abstraction that will allow us to add the stack. Alongside these changes, `ParseState` has been augmented with a `PubContext` type that is utilized on public APIs, both maintaining BC with existing code and keeping these implementation details encapsulated. This does make a bit of a mess of the internal implementation, though, with `asg_mut()` sprinkled about, so maybe the next commit can clean that up a bit. EDIT: After adding `AsMut` to a bunch of asg::graph::object::* methods, I decided against it, because it messes with the inferred ownership, requiring explicit borrows via `as_mut()` where they were not required before. I think the existing code is easier to reason about than what would otherwise result from having `mut asg: impl AsMut<Asg>` everwhere. DEV-13708main
parent
fc569f7551
commit
b1ce7aaf29
|
@ -107,16 +107,17 @@ impl ParseState for AirAggregate {
|
||||||
type Token = Air;
|
type Token = Air;
|
||||||
type Object = ();
|
type Object = ();
|
||||||
type Error = AsgError;
|
type Error = AsgError;
|
||||||
|
type Context = AirAggregateCtx;
|
||||||
|
|
||||||
/// Destination [`Asg`] that this parser lowers into.
|
/// Destination [`Asg`] that this parser lowers into.
|
||||||
///
|
///
|
||||||
/// This ASG will be yielded by [`crate::parse::Parser::finalize`].
|
/// This ASG will be yielded by [`crate::parse::Parser::finalize`].
|
||||||
type Context = Asg;
|
type PubContext = Asg;
|
||||||
|
|
||||||
fn parse_token(
|
fn parse_token(
|
||||||
self,
|
self,
|
||||||
tok: Self::Token,
|
tok: Self::Token,
|
||||||
asg: &mut Self::Context,
|
ctx: &mut Self::Context,
|
||||||
) -> crate::parse::TransitionResult<Self> {
|
) -> crate::parse::TransitionResult<Self> {
|
||||||
use ir::{
|
use ir::{
|
||||||
AirBind::*, AirIdent::*, AirPkg::*, AirSubsets::*, AirTodo::*,
|
AirBind::*, AirIdent::*, AirPkg::*, AirSubsets::*, AirTodo::*,
|
||||||
|
@ -128,7 +129,8 @@ impl ParseState for AirAggregate {
|
||||||
(st, AirTodo(Todo(_))) => Transition(st).incomplete(),
|
(st, AirTodo(Todo(_))) => Transition(st).incomplete(),
|
||||||
|
|
||||||
(Empty, AirPkg(PkgStart(span))) => {
|
(Empty, AirPkg(PkgStart(span))) => {
|
||||||
let oi_pkg = asg.create(Pkg::new(span)).root(asg);
|
let oi_pkg =
|
||||||
|
ctx.asg_mut().create(Pkg::new(span)).root(ctx.asg_mut());
|
||||||
Transition(Toplevel(oi_pkg, AirExprAggregate::new_in(oi_pkg)))
|
Transition(Toplevel(oi_pkg, AirExprAggregate::new_in(oi_pkg)))
|
||||||
.incomplete()
|
.incomplete()
|
||||||
}
|
}
|
||||||
|
@ -145,7 +147,7 @@ impl ParseState for AirAggregate {
|
||||||
|
|
||||||
// No expression was started.
|
// No expression was started.
|
||||||
(Toplevel(oi_pkg, _expr), AirPkg(PkgEnd(span))) => {
|
(Toplevel(oi_pkg, _expr), AirPkg(PkgEnd(span))) => {
|
||||||
oi_pkg.close(asg, span);
|
oi_pkg.close(ctx.asg_mut(), span);
|
||||||
Transition(Empty).incomplete()
|
Transition(Empty).incomplete()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,21 +184,21 @@ impl ParseState for AirAggregate {
|
||||||
// unreachable paths)
|
// unreachable paths)
|
||||||
// because of the different inner types.
|
// because of the different inner types.
|
||||||
(PkgExpr(oi_pkg, expr), AirExpr(etok)) => {
|
(PkgExpr(oi_pkg, expr), AirExpr(etok)) => {
|
||||||
Self::delegate_expr(asg, oi_pkg, expr, etok)
|
Self::delegate_expr(ctx, oi_pkg, expr, etok)
|
||||||
}
|
}
|
||||||
(PkgExpr(oi_pkg, expr), AirBind(etok)) => {
|
(PkgExpr(oi_pkg, expr), AirBind(etok)) => {
|
||||||
Self::delegate_expr(asg, oi_pkg, expr, etok)
|
Self::delegate_expr(ctx, oi_pkg, expr, etok)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Template parsing.
|
// Template parsing.
|
||||||
(PkgTpl(oi_pkg, stored_expr, tplst), AirExpr(ttok)) => {
|
(PkgTpl(oi_pkg, stored_expr, tplst), AirExpr(ttok)) => {
|
||||||
Self::delegate_tpl(asg, oi_pkg, stored_expr, tplst, ttok)
|
Self::delegate_tpl(ctx, oi_pkg, stored_expr, tplst, ttok)
|
||||||
}
|
}
|
||||||
(PkgTpl(oi_pkg, stored_expr, tplst), AirBind(ttok)) => {
|
(PkgTpl(oi_pkg, stored_expr, tplst), AirBind(ttok)) => {
|
||||||
Self::delegate_tpl(asg, oi_pkg, stored_expr, tplst, ttok)
|
Self::delegate_tpl(ctx, oi_pkg, stored_expr, tplst, ttok)
|
||||||
}
|
}
|
||||||
(PkgTpl(oi_pkg, stored_expr, tplst), AirTpl(ttok)) => {
|
(PkgTpl(oi_pkg, stored_expr, tplst), AirTpl(ttok)) => {
|
||||||
Self::delegate_tpl(asg, oi_pkg, stored_expr, tplst, ttok)
|
Self::delegate_tpl(ctx, oi_pkg, stored_expr, tplst, ttok)
|
||||||
}
|
}
|
||||||
|
|
||||||
(PkgTpl(..), tok @ AirPkg(PkgStart(..))) => {
|
(PkgTpl(..), tok @ AirPkg(PkgStart(..))) => {
|
||||||
|
@ -211,10 +213,10 @@ impl ParseState for AirAggregate {
|
||||||
}
|
}
|
||||||
|
|
||||||
(PkgExpr(oi_pkg, expr), AirPkg(PkgEnd(span))) => {
|
(PkgExpr(oi_pkg, expr), AirPkg(PkgEnd(span))) => {
|
||||||
match expr.is_accepting(asg) {
|
match expr.is_accepting(ctx) {
|
||||||
true => {
|
true => {
|
||||||
// TODO: this is duplicated with the above
|
// TODO: this is duplicated with the above
|
||||||
oi_pkg.close(asg, span);
|
oi_pkg.close(ctx.asg_mut(), span);
|
||||||
Transition(Empty).incomplete()
|
Transition(Empty).incomplete()
|
||||||
}
|
}
|
||||||
false => Transition(PkgExpr(oi_pkg, expr))
|
false => Transition(PkgExpr(oi_pkg, expr))
|
||||||
|
@ -223,7 +225,7 @@ impl ParseState for AirAggregate {
|
||||||
}
|
}
|
||||||
|
|
||||||
(PkgTpl(oi_pkg, stored_expr, tplst), AirPkg(PkgEnd(span))) => {
|
(PkgTpl(oi_pkg, stored_expr, tplst), AirPkg(PkgEnd(span))) => {
|
||||||
match tplst.is_accepting(asg) {
|
match tplst.is_accepting(ctx) {
|
||||||
true => Transition(PkgExpr(oi_pkg, stored_expr))
|
true => Transition(PkgExpr(oi_pkg, stored_expr))
|
||||||
.incomplete()
|
.incomplete()
|
||||||
.with_lookahead(AirPkg(PkgEnd(span))),
|
.with_lookahead(AirPkg(PkgEnd(span))),
|
||||||
|
@ -236,25 +238,31 @@ impl ParseState for AirAggregate {
|
||||||
Transition(Empty).err(AsgError::PkgExpected(tok.span()))
|
Transition(Empty).err(AsgError::PkgExpected(tok.span()))
|
||||||
}
|
}
|
||||||
|
|
||||||
(Empty, AirIdent(IdentDecl(name, kind, src))) => {
|
(Empty, AirIdent(IdentDecl(name, kind, src))) => ctx
|
||||||
asg.declare(name, kind, src).map(|_| ()).transition(Empty)
|
.asg_mut()
|
||||||
}
|
.declare(name, kind, src)
|
||||||
|
.map(|_| ())
|
||||||
|
.transition(Empty),
|
||||||
|
|
||||||
(Empty, AirIdent(IdentExternDecl(name, kind, src))) => asg
|
(Empty, AirIdent(IdentExternDecl(name, kind, src))) => ctx
|
||||||
|
.asg_mut()
|
||||||
.declare_extern(name, kind, src)
|
.declare_extern(name, kind, src)
|
||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
.transition(Empty),
|
.transition(Empty),
|
||||||
|
|
||||||
(Empty, AirIdent(IdentDep(sym, dep))) => {
|
(Empty, AirIdent(IdentDep(sym, dep))) => {
|
||||||
asg.add_dep_lookup_global(sym, dep);
|
ctx.asg_mut().add_dep_lookup_global(sym, dep);
|
||||||
Transition(Empty).incomplete()
|
Transition(Empty).incomplete()
|
||||||
}
|
}
|
||||||
|
|
||||||
(Empty, AirIdent(IdentFragment(sym, text))) => {
|
(Empty, AirIdent(IdentFragment(sym, text))) => ctx
|
||||||
asg.set_fragment(sym, text).map(|_| ()).transition(Empty)
|
.asg_mut()
|
||||||
}
|
.set_fragment(sym, text)
|
||||||
|
.map(|_| ())
|
||||||
|
.transition(Empty),
|
||||||
|
|
||||||
(Empty, AirIdent(IdentRoot(sym))) => {
|
(Empty, AirIdent(IdentRoot(sym))) => {
|
||||||
|
let asg = ctx.asg_mut();
|
||||||
let obj = asg.lookup_global_or_missing(sym);
|
let obj = asg.lookup_global_or_missing(sym);
|
||||||
asg.add_root(obj);
|
asg.add_root(obj);
|
||||||
|
|
||||||
|
@ -322,5 +330,48 @@ impl AirAggregate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Additional parser context.
|
||||||
|
///
|
||||||
|
/// TODO: This was introduced to hold additional context;
|
||||||
|
/// see future commit.
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct AirAggregateCtx(Asg);
|
||||||
|
|
||||||
|
impl AirAggregateCtx {
|
||||||
|
fn asg_mut(&mut self) -> &mut Asg {
|
||||||
|
self.as_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsRef<Asg> for AirAggregateCtx {
|
||||||
|
fn as_ref(&self) -> &Asg {
|
||||||
|
match self {
|
||||||
|
Self(asg) => asg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsMut<Asg> for AirAggregateCtx {
|
||||||
|
fn as_mut(&mut self) -> &mut Asg {
|
||||||
|
match self {
|
||||||
|
Self(asg) => asg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<AirAggregateCtx> for Asg {
|
||||||
|
fn from(ctx: AirAggregateCtx) -> Self {
|
||||||
|
match ctx {
|
||||||
|
AirAggregateCtx(asg) => asg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Asg> for AirAggregateCtx {
|
||||||
|
fn from(asg: Asg) -> Self {
|
||||||
|
Self(asg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test;
|
mod test;
|
||||||
|
|
|
@ -27,6 +27,7 @@ use super::{
|
||||||
Asg, AsgError, ObjectIndex,
|
Asg, AsgError, ObjectIndex,
|
||||||
},
|
},
|
||||||
ir::AirBindableExpr,
|
ir::AirBindableExpr,
|
||||||
|
AirAggregateCtx,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
asg::{graph::object::ObjectRelTo, Ident, ObjectKind},
|
asg::{graph::object::ObjectRelTo, Ident, ObjectKind},
|
||||||
|
@ -87,17 +88,19 @@ impl<O: ObjectKind, S: RootStrategy<O>> ParseState for AirExprAggregate<O, S> {
|
||||||
type Token = AirBindableExpr;
|
type Token = AirBindableExpr;
|
||||||
type Object = ();
|
type Object = ();
|
||||||
type Error = AsgError;
|
type Error = AsgError;
|
||||||
type Context = Asg;
|
type Context = AirAggregateCtx;
|
||||||
|
|
||||||
fn parse_token(
|
fn parse_token(
|
||||||
self,
|
self,
|
||||||
tok: Self::Token,
|
tok: Self::Token,
|
||||||
asg: &mut Self::Context,
|
ctx: &mut Self::Context,
|
||||||
) -> crate::parse::TransitionResult<Self::Super> {
|
) -> crate::parse::TransitionResult<Self::Super> {
|
||||||
use super::ir::{AirBind::*, AirExpr::*};
|
use super::ir::{AirBind::*, AirExpr::*};
|
||||||
use AirBindableExpr::*;
|
use AirBindableExpr::*;
|
||||||
use AirExprAggregate::*;
|
use AirExprAggregate::*;
|
||||||
|
|
||||||
|
let asg = ctx.asg_mut();
|
||||||
|
|
||||||
match (self, tok) {
|
match (self, tok) {
|
||||||
(Ready(root, es, _), AirExpr(ExprStart(op, span))) => {
|
(Ready(root, es, _), AirExpr(ExprStart(op, span))) => {
|
||||||
let oi = asg.create(Expr::new(op, span));
|
let oi = asg.create(Expr::new(op, span));
|
||||||
|
|
|
@ -25,7 +25,7 @@ use super::{
|
||||||
super::{graph::object::Tpl, Asg, AsgError, ObjectIndex},
|
super::{graph::object::Tpl, Asg, AsgError, ObjectIndex},
|
||||||
expr::AirExprAggregateStoreDangling,
|
expr::AirExprAggregateStoreDangling,
|
||||||
ir::AirTemplatable,
|
ir::AirTemplatable,
|
||||||
AirExprAggregate,
|
AirAggregateCtx, AirExprAggregate,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
asg::{
|
asg::{
|
||||||
|
@ -244,12 +244,12 @@ where
|
||||||
type Token = AirTemplatable;
|
type Token = AirTemplatable;
|
||||||
type Object = ();
|
type Object = ();
|
||||||
type Error = AsgError;
|
type Error = AsgError;
|
||||||
type Context = Asg;
|
type Context = AirAggregateCtx;
|
||||||
|
|
||||||
fn parse_token(
|
fn parse_token(
|
||||||
self,
|
self,
|
||||||
tok: Self::Token,
|
tok: Self::Token,
|
||||||
asg: &mut Self::Context,
|
ctx: &mut Self::Context,
|
||||||
) -> TransitionResult<Self::Super> {
|
) -> TransitionResult<Self::Super> {
|
||||||
use super::ir::{AirBind::*, AirTpl::*};
|
use super::ir::{AirBind::*, AirTpl::*};
|
||||||
use AirTemplatable::*;
|
use AirTemplatable::*;
|
||||||
|
@ -257,7 +257,7 @@ where
|
||||||
|
|
||||||
match (self, tok) {
|
match (self, tok) {
|
||||||
(Ready(ois), AirTpl(TplStart(span))) => {
|
(Ready(ois), AirTpl(TplStart(span))) => {
|
||||||
let oi_tpl = asg.create(Tpl::new(span));
|
let oi_tpl = ctx.asg_mut().create(Tpl::new(span));
|
||||||
|
|
||||||
Transition(Toplevel(
|
Transition(Toplevel(
|
||||||
ois,
|
ois,
|
||||||
|
@ -272,24 +272,27 @@ where
|
||||||
"nested tpl open"
|
"nested tpl open"
|
||||||
),
|
),
|
||||||
|
|
||||||
(Toplevel(ois, tpl, expr), AirBind(BindIdent(id))) => asg
|
(Toplevel(ois, tpl, expr), AirBind(BindIdent(id))) => {
|
||||||
.lookup_global_or_missing(id)
|
let asg = ctx.asg_mut();
|
||||||
|
|
||||||
|
asg.lookup_global_or_missing(id)
|
||||||
.bind_definition(asg, id, tpl.oi())
|
.bind_definition(asg, id, tpl.oi())
|
||||||
.map(|oi_ident| ois.defines(asg, oi_ident))
|
.map(|oi_ident| ois.defines(asg, oi_ident))
|
||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
.transition(Toplevel(ois, tpl.identify(id), expr)),
|
.transition(Toplevel(ois, tpl.identify(id), expr))
|
||||||
|
}
|
||||||
|
|
||||||
(Toplevel(ois, tpl, expr), AirBind(RefIdent(id))) => {
|
(Toplevel(ois, tpl, expr), AirBind(RefIdent(id))) => {
|
||||||
tpl.oi().apply_named_tpl(asg, id);
|
tpl.oi().apply_named_tpl(ctx.asg_mut(), id);
|
||||||
Transition(Toplevel(ois, tpl, expr)).incomplete()
|
Transition(Toplevel(ois, tpl, expr)).incomplete()
|
||||||
}
|
}
|
||||||
|
|
||||||
(Toplevel(ois, tpl, expr), AirTpl(TplMetaStart(span))) => {
|
(Toplevel(ois, tpl, expr), AirTpl(TplMetaStart(span))) => {
|
||||||
let oi_meta = asg.create(Meta::new_required(span));
|
let oi_meta = ctx.asg_mut().create(Meta::new_required(span));
|
||||||
Transition(TplMeta(ois, tpl, expr, oi_meta)).incomplete()
|
Transition(TplMeta(ois, tpl, expr, oi_meta)).incomplete()
|
||||||
}
|
}
|
||||||
(TplMeta(ois, tpl, expr, oi_meta), AirTpl(TplMetaEnd(cspan))) => {
|
(TplMeta(ois, tpl, expr, oi_meta), AirTpl(TplMetaEnd(cspan))) => {
|
||||||
oi_meta.close(asg, cspan);
|
oi_meta.close(ctx.asg_mut(), cspan);
|
||||||
Transition(Toplevel(ois, tpl, expr)).incomplete()
|
Transition(Toplevel(ois, tpl, expr)).incomplete()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,13 +301,13 @@ where
|
||||||
ois,
|
ois,
|
||||||
tpl,
|
tpl,
|
||||||
expr,
|
expr,
|
||||||
oi_meta.assign_lexeme(asg, lexeme),
|
oi_meta.assign_lexeme(ctx.asg_mut(), lexeme),
|
||||||
))
|
))
|
||||||
.incomplete()
|
.incomplete()
|
||||||
}
|
}
|
||||||
|
|
||||||
(TplMeta(ois, tpl, expr, oi_meta), AirBind(BindIdent(name))) => {
|
(TplMeta(ois, tpl, expr, oi_meta), AirBind(BindIdent(name))) => {
|
||||||
oi_meta.identify_as_tpl_param(asg, tpl.oi(), name);
|
oi_meta.identify_as_tpl_param(ctx.asg_mut(), tpl.oi(), name);
|
||||||
Transition(TplMeta(ois, tpl, expr, oi_meta)).incomplete()
|
Transition(TplMeta(ois, tpl, expr, oi_meta)).incomplete()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,13 +350,13 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
(Toplevel(ois, tpl, _expr_done), AirTpl(TplEnd(span))) => {
|
(Toplevel(ois, tpl, _expr_done), AirTpl(TplEnd(span))) => {
|
||||||
tpl.close(asg, span).transition(Ready(ois))
|
tpl.close(ctx.asg_mut(), span).transition(Ready(ois))
|
||||||
}
|
}
|
||||||
|
|
||||||
(TplExpr(ois, tpl, expr), AirTpl(TplEnd(span))) => {
|
(TplExpr(ois, tpl, expr), AirTpl(TplEnd(span))) => {
|
||||||
// TODO: duplicated with AirAggregate
|
// TODO: duplicated with AirAggregate
|
||||||
if expr.is_accepting(asg) {
|
if expr.is_accepting(ctx) {
|
||||||
tpl.close(asg, span).transition(Ready(ois))
|
tpl.close(ctx.asg_mut(), span).transition(Ready(ois))
|
||||||
} else {
|
} else {
|
||||||
Transition(TplExpr(ois, tpl, expr))
|
Transition(TplExpr(ois, tpl, expr))
|
||||||
.err(AsgError::InvalidTplEndContext(span))
|
.err(AsgError::InvalidTplEndContext(span))
|
||||||
|
@ -361,7 +364,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
(Toplevel(ois, tpl, expr_done), AirTpl(TplEndRef(span))) => {
|
(Toplevel(ois, tpl, expr_done), AirTpl(TplEndRef(span))) => {
|
||||||
tpl.oi().expand_into(asg, ois.oi_target());
|
tpl.oi().expand_into(ctx.asg_mut(), ois.oi_target());
|
||||||
|
|
||||||
Transition(Toplevel(ois, tpl.anonymous_reachable(), expr_done))
|
Transition(Toplevel(ois, tpl.anonymous_reachable(), expr_done))
|
||||||
.incomplete()
|
.incomplete()
|
||||||
|
@ -369,7 +372,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
(TplExpr(ois, tpl, expr_done), AirTpl(TplEndRef(span))) => {
|
(TplExpr(ois, tpl, expr_done), AirTpl(TplEndRef(span))) => {
|
||||||
tpl.oi().expand_into(asg, ois.oi_target());
|
tpl.oi().expand_into(ctx.asg_mut(), ois.oi_target());
|
||||||
|
|
||||||
Transition(TplExpr(ois, tpl.anonymous_reachable(), expr_done))
|
Transition(TplExpr(ois, tpl.anonymous_reachable(), expr_done))
|
||||||
.incomplete()
|
.incomplete()
|
||||||
|
@ -379,10 +382,10 @@ where
|
||||||
(
|
(
|
||||||
Toplevel(ois, tpl, expr) | TplExpr(ois, tpl, expr),
|
Toplevel(ois, tpl, expr) | TplExpr(ois, tpl, expr),
|
||||||
AirExpr(etok),
|
AirExpr(etok),
|
||||||
) => Self::delegate_expr(asg, ois, tpl, expr, etok),
|
) => Self::delegate_expr(ctx, ois, tpl, expr, etok),
|
||||||
|
|
||||||
(TplExpr(ois, tpl, expr), AirBind(etok)) => {
|
(TplExpr(ois, tpl, expr), AirBind(etok)) => {
|
||||||
Self::delegate_expr(asg, ois, tpl, expr, etok)
|
Self::delegate_expr(ctx, ois, tpl, expr, etok)
|
||||||
}
|
}
|
||||||
|
|
||||||
(TplExpr(..), AirTpl(TplStart(span))) => {
|
(TplExpr(..), AirTpl(TplStart(span))) => {
|
||||||
|
|
|
@ -138,9 +138,9 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
fn lower_with_context<U, E>(
|
fn lower_with_context<U, E>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: impl Into<LS::Context>,
|
ctx: impl Into<LS::PubContext>,
|
||||||
f: impl FnOnce(&mut LowerIter<S, Self, LS, EW>) -> Result<U, E>,
|
f: impl FnOnce(&mut LowerIter<S, Self, LS, EW>) -> Result<U, E>,
|
||||||
) -> Result<(U, LS::Context), E>
|
) -> Result<(U, LS::PubContext), E>
|
||||||
where
|
where
|
||||||
Self: Iterator<Item = WidenedParsedResult<S, EW>> + Sized,
|
Self: Iterator<Item = WidenedParsedResult<S, EW>> + Sized,
|
||||||
E: Diagnostic + From<FinalizeError>,
|
E: Diagnostic + From<FinalizeError>,
|
||||||
|
|
|
@ -497,9 +497,9 @@ pub struct FinalizedParser<S: ParseState>(S::Context);
|
||||||
|
|
||||||
impl<S: ParseState> FinalizedParser<S> {
|
impl<S: ParseState> FinalizedParser<S> {
|
||||||
/// Take ownership over the inner [`ParseState::Context`].
|
/// Take ownership over the inner [`ParseState::Context`].
|
||||||
pub fn into_context(self) -> S::Context {
|
pub fn into_context(self) -> S::PubContext {
|
||||||
match self {
|
match self {
|
||||||
Self(ctx) => ctx,
|
Self(ctx) => ctx.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,6 +169,16 @@ where
|
||||||
/// otherwise-immutable [`ParseState`].
|
/// otherwise-immutable [`ParseState`].
|
||||||
type Context: Debug = context::Empty;
|
type Context: Debug = context::Empty;
|
||||||
|
|
||||||
|
/// Public representation of [`Self::Context`].
|
||||||
|
///
|
||||||
|
/// If [`Self::Context`] holds internal state that isn't intended to be
|
||||||
|
/// exposed via a public API,
|
||||||
|
/// this represents the type that should be used in its place.
|
||||||
|
/// Since public APIs include both input and output,
|
||||||
|
/// this type must be convertable to _and_ from [`Self::Context`].
|
||||||
|
type PubContext: Debug + From<Self::Context> + Into<Self::Context> =
|
||||||
|
Self::Context;
|
||||||
|
|
||||||
/// Construct a parser with a [`Default`] state.
|
/// Construct a parser with a [`Default`] state.
|
||||||
///
|
///
|
||||||
/// Whether this method is helpful or provides any clarity depends on
|
/// Whether this method is helpful or provides any clarity depends on
|
||||||
|
@ -198,12 +208,12 @@ where
|
||||||
/// see [`Parser::finalize`].
|
/// see [`Parser::finalize`].
|
||||||
fn parse_with_context<I: TokenStream<Self::Token>>(
|
fn parse_with_context<I: TokenStream<Self::Token>>(
|
||||||
toks: I,
|
toks: I,
|
||||||
ctx: Self::Context,
|
ctx: Self::PubContext,
|
||||||
) -> Parser<Self, I>
|
) -> Parser<Self, I>
|
||||||
where
|
where
|
||||||
Self: ClosedParseState + Default,
|
Self: ClosedParseState + Default,
|
||||||
{
|
{
|
||||||
Parser::from((toks, ctx))
|
Parser::from((toks, ctx.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a single [`Token`] and optionally perform a state transition.
|
/// Parse a single [`Token`] and optionally perform a state transition.
|
||||||
|
|
Loading…
Reference in New Issue